IsColinear() публичный статический Метод

public static IsColinear ( Int3 a, Int3 b, Int3 c ) : bool
a Int3
b Int3
c Int3
Результат bool
Пример #1
0
 public int GetColinearEdge(Int3 a, Int3 b, int startEdge, int count)
 {
     Int3[] staticVerts = TriangleMeshNode._staticVerts;
     this.GetPoints(out staticVerts[0], out staticVerts[1], out staticVerts[2]);
     for (int i = 0; i < count; i++)
     {
         int num  = (startEdge + i) % 3;
         int num2 = (num + 1) % 3;
         if (Polygon.IsColinear(staticVerts[num], staticVerts[num2], a) && Polygon.IsColinear(staticVerts[num], staticVerts[num2], b))
         {
             return(num);
         }
     }
     return(-1);
 }
Пример #2
0
 public int GetColinearEdge(VInt3 a, VInt3 b, int startEdge, int count)
 {
     VInt3[] numArray = _staticVerts;
     this.GetPoints(out numArray[0], out numArray[1], out numArray[2]);
     for (int i = 0; i < count; i++)
     {
         int index = (startEdge + i) % 3;
         int num3  = (index + 1) % 3;
         if (Polygon.IsColinear(numArray[index], numArray[num3], a) && Polygon.IsColinear(numArray[index], numArray[num3], b))
         {
             return(index);
         }
     }
     return(-1);
 }
Пример #3
0
        public int GetColinearEdge(VInt3 a, VInt3 b)
        {
            VInt3 num;
            VInt3 num2;
            VInt3 num3;

            this.GetPoints(out num, out num2, out num3);
            if (Polygon.IsColinear(num, num2, a) && Polygon.IsColinear(num, num2, b))
            {
                return(0);
            }
            if (Polygon.IsColinear(num2, num3, a) && Polygon.IsColinear(num2, num3, b))
            {
                return(1);
            }
            if (Polygon.IsColinear(num3, num, a) && Polygon.IsColinear(num3, num, b))
            {
                return(2);
            }
            return(-1);
        }
Пример #4
0
        public int GetColinearEdge(Int3 a, Int3 b)
        {
            Int3 vInt;
            Int3 vInt2;
            Int3 vInt3;

            this.GetPoints(out vInt, out vInt2, out vInt3);
            if (Polygon.IsColinear(vInt, vInt2, a) && Polygon.IsColinear(vInt, vInt2, b))
            {
                return(0);
            }
            if (Polygon.IsColinear(vInt2, vInt3, a) && Polygon.IsColinear(vInt2, vInt3, b))
            {
                return(1);
            }
            if (Polygon.IsColinear(vInt3, vInt, a) && Polygon.IsColinear(vInt3, vInt, b))
            {
                return(2);
            }
            return(-1);
        }
Пример #5
0
        private void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices)
        {
            if (vectorVertices.Length == 0 || triangles.Length == 0)
            {
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                this.nodes       = new TriangleMeshNode[0];
                return;
            }
            vertices = new Int3[vectorVertices.Length];
            int num = 0;

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = (Int3)this.matrix.MultiplyPoint3x4(vectorVertices[i]);
            }
            Dictionary <Int3, int> dictionary = new Dictionary <Int3, int>();

            int[] array = new int[vertices.Length];
            for (int j = 0; j < vertices.Length; j++)
            {
                if (!dictionary.ContainsKey(vertices[j]))
                {
                    array[num] = j;
                    dictionary.Add(vertices[j], num);
                    num++;
                }
            }
            for (int k = 0; k < triangles.Length; k++)
            {
                Int3 key = vertices[triangles[k]];
                triangles[k] = dictionary[key];
            }
            Int3[] array2 = vertices;
            vertices         = new Int3[num];
            originalVertices = new Vector3[num];
            for (int l = 0; l < num; l++)
            {
                vertices[l]         = array2[array[l]];
                originalVertices[l] = vectorVertices[array[l]];
            }
            this.nodes = new TriangleMeshNode[triangles.Length / 3];
            int graphIndex = this.active.astarData.GetGraphIndex(this);

            for (int m = 0; m < this.nodes.Length; m++)
            {
                this.nodes[m] = new TriangleMeshNode(this.active);
                TriangleMeshNode triangleMeshNode = this.nodes[m];
                triangleMeshNode.GraphIndex = (uint)graphIndex;
                triangleMeshNode.Penalty    = this.initialPenalty;
                triangleMeshNode.Walkable   = true;
                triangleMeshNode.v0         = triangles[m * 3];
                triangleMeshNode.v1         = triangles[m * 3 + 1];
                triangleMeshNode.v2         = triangles[m * 3 + 2];
                if (!Polygon.IsClockwise(vertices[triangleMeshNode.v0], vertices[triangleMeshNode.v1], vertices[triangleMeshNode.v2]))
                {
                    int v = triangleMeshNode.v0;
                    triangleMeshNode.v0 = triangleMeshNode.v2;
                    triangleMeshNode.v2 = v;
                }
                if (Polygon.IsColinear(vertices[triangleMeshNode.v0], vertices[triangleMeshNode.v1], vertices[triangleMeshNode.v2]))
                {
                    Debug.DrawLine((Vector3)vertices[triangleMeshNode.v0], (Vector3)vertices[triangleMeshNode.v1], Color.red);
                    Debug.DrawLine((Vector3)vertices[triangleMeshNode.v1], (Vector3)vertices[triangleMeshNode.v2], Color.red);
                    Debug.DrawLine((Vector3)vertices[triangleMeshNode.v2], (Vector3)vertices[triangleMeshNode.v0], Color.red);
                }
                triangleMeshNode.UpdatePositionFromVertices();
            }
            Dictionary <Int2, TriangleMeshNode> dictionary2 = new Dictionary <Int2, TriangleMeshNode>();
            int n    = 0;
            int num2 = 0;

            while (n < triangles.Length)
            {
                dictionary2[new Int2(triangles[n], triangles[n + 1])]     = this.nodes[num2];
                dictionary2[new Int2(triangles[n + 1], triangles[n + 2])] = this.nodes[num2];
                dictionary2[new Int2(triangles[n + 2], triangles[n])]     = this.nodes[num2];
                num2++;
                n += 3;
            }
            List <MeshNode> list  = new List <MeshNode>();
            List <uint>     list2 = new List <uint>();
            int             num3  = 0;
            int             num4  = 0;

            while (num3 < triangles.Length)
            {
                list.Clear();
                list2.Clear();
                TriangleMeshNode triangleMeshNode2 = this.nodes[num4];
                for (int num5 = 0; num5 < 3; num5++)
                {
                    TriangleMeshNode triangleMeshNode3;
                    if (dictionary2.TryGetValue(new Int2(triangles[num3 + (num5 + 1) % 3], triangles[num3 + num5]), out triangleMeshNode3))
                    {
                        list.Add(triangleMeshNode3);
                        list2.Add((uint)(triangleMeshNode2.position - triangleMeshNode3.position).costMagnitude);
                    }
                }
                triangleMeshNode2.connections     = list.ToArray();
                triangleMeshNode2.connectionCosts = list2.ToArray();
                num4++;
                num3 += 3;
            }
            NavMeshGraph.RebuildBBTree(this);
        }
Пример #6
0
        /** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */
        void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices)
        {
            Profiler.BeginSample("Init");

            if (vectorVertices.Length == 0 || triangles.Length == 0)
            {
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                //graph.CreateNodes (0);
                nodes = new TriangleMeshNode[0];
                return;
            }

            vertices = new Int3[vectorVertices.Length];

            int c = 0;

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = (Int3)matrix.MultiplyPoint3x4(vectorVertices[i]);
            }

            var hashedVerts = new Dictionary <Int3, int> ();

            var newVertices = new int[vertices.Length];

            Profiler.EndSample();
            Profiler.BeginSample("Hashing");

            for (int i = 0; i < vertices.Length; i++)
            {
                if (!hashedVerts.ContainsKey(vertices[i]))
                {
                    newVertices[c] = i;
                    hashedVerts.Add(vertices[i], c);
                    c++;
                }
            }

            for (int x = 0; x < triangles.Length; x++)
            {
                Int3 vertex = vertices[triangles[x]];

                triangles[x] = hashedVerts[vertex];
            }

            Int3[] totalIntVertices = vertices;
            vertices         = new Int3[c];
            originalVertices = new Vector3[c];
            for (int i = 0; i < c; i++)
            {
                vertices[i]         = totalIntVertices[newVertices[i]];
                originalVertices[i] = vectorVertices[newVertices[i]];
            }

            Profiler.EndSample();
            Profiler.BeginSample("Constructing Nodes");

            nodes = new TriangleMeshNode[triangles.Length / 3];

            int graphIndex = active.astarData.GetGraphIndex(this);

            // Does not have to set this, it is set in ScanInternal
            //TriangleMeshNode.SetNavmeshHolder ((int)graphIndex,this);

            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i] = new TriangleMeshNode(active);
                TriangleMeshNode node = nodes[i];                //new MeshNode ();

                node.GraphIndex = (uint)graphIndex;
                node.Penalty    = initialPenalty;
                node.Walkable   = true;


                node.v0 = triangles[i * 3];
                node.v1 = triangles[i * 3 + 1];
                node.v2 = triangles[i * 3 + 2];

                if (!Polygon.IsClockwise(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
                {
                    //Debug.DrawLine (vertices[node.v0],vertices[node.v1],Color.red);
                    //Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
                    //Debug.DrawLine (vertices[node.v2],vertices[node.v0],Color.red);

                    int tmp = node.v0;
                    node.v0 = node.v2;
                    node.v2 = tmp;
                }

                if (Polygon.IsColinear(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
                {
                    Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.red);
                    Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.red);
                    Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.red);
                }

                // Make sure position is correctly set
                node.UpdatePositionFromVertices();
            }

            Profiler.EndSample();

            var sides = new Dictionary <Int2, TriangleMeshNode>();

            for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
            {
                sides[new Int2(triangles[i + 0], triangles[i + 1])] = nodes[j];
                sides[new Int2(triangles[i + 1], triangles[i + 2])] = nodes[j];
                sides[new Int2(triangles[i + 2], triangles[i + 0])] = nodes[j];
            }

            Profiler.BeginSample("Connecting Nodes");

            var connections     = new List <MeshNode> ();
            var connectionCosts = new List <uint> ();

            for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
            {
                connections.Clear();
                connectionCosts.Clear();

                TriangleMeshNode node = nodes[j];

                for (int q = 0; q < 3; q++)
                {
                    TriangleMeshNode other;
                    if (sides.TryGetValue(new Int2(triangles[i + ((q + 1) % 3)], triangles[i + q]), out other))
                    {
                        connections.Add(other);
                        connectionCosts.Add((uint)(node.position - other.position).costMagnitude);
                    }
                }

                node.connections     = connections.ToArray();
                node.connectionCosts = connectionCosts.ToArray();
            }

            Profiler.EndSample();
            Profiler.BeginSample("Rebuilding BBTree");

            RebuildBBTree(this);

            Profiler.EndSample();

#if ASTARDEBUG
            for (int i = 0; i < nodes.Length; i++)
            {
                TriangleMeshNode node = nodes[i] as TriangleMeshNode;

                float a1 = Polygon.TriangleArea2((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], (Vector3)vertices[node.v2]);

                long a2 = Polygon.TriangleArea2(vertices[node.v0], vertices[node.v1], vertices[node.v2]);
                if (a1 * a2 < 0)
                {
                    Debug.LogError(a1 + " " + a2);
                }


                if (Polygon.IsClockwise(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
                {
                    Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.green);
                    Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.green);
                    Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.green);
                }
                else
                {
                    Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.red);
                    Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.red);
                    Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.red);
                }
            }
#endif
            //Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
        }
Пример #7
0
        /** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */
        public static void GenerateNodes(NavGraph graph, Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices)
        {
            if (!(graph is INavmesh))
            {
                Debug.LogError("The specified graph does not implement interface 'INavmesh'");
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                graph.nodes      = graph.CreateNodes(0);
                return;
            }

            if (vectorVertices.Length == 0 || triangles.Length == 0)
            {
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                graph.nodes      = graph.CreateNodes(0);
                return;
            }

            vertices = new Int3[vectorVertices.Length];

            //Backup the original vertices
            //for (int i=0;i<vectorVertices.Length;i++) {
            //	vectorVertices[i] = graph.matrix.MultiplyPoint (vectorVertices[i]);
            //}

            int c = 0;

            /*int maxX = 0;
             * int maxZ = 0;
             *
             * //Almost infinity
             * int minX = 0xFFFFFFF;
             * int minZ = 0xFFFFFFF;*/

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = (Int3)graph.matrix.MultiplyPoint(vectorVertices[i]);

                /*maxX = Mathfx.Max (vertices[i].x, maxX);
                *  maxZ = Mathfx.Max (vertices[i].z, maxZ);
                *  minX = Mathfx.Min (vertices[i].x, minX);
                *  minZ = Mathfx.Min (vertices[i].z, minZ);*/
            }

            //maxX = maxX-minX;
            //maxZ = maxZ-minZ;

            Dictionary <Int3, int> hashedVerts = new Dictionary <Int3, int> ();

            int[] newVertices = new int[vertices.Length];

            for (int i = 0; i < vertices.Length - 1; i++)
            {
                //int hash = Mathfx.ComputeVertexHash (vertices[i].x,vertices[i].y,vertices[i].z);

                //(vertices[i].x-minX)+(vertices[i].z-minX)*maxX+vertices[i].y*maxX*maxZ;
                //if (sortedVertices[i] != sortedVertices[i+1]) {
                if (!hashedVerts.ContainsKey(vertices[i]))
                {
                    newVertices[c] = i;
                    hashedVerts.Add(vertices[i], c);
                    c++;
                }                // else {
                //Debug.Log ("Hash Duplicate "+hash+" "+vertices[i].ToString ());
                //}
            }

            newVertices[c] = vertices.Length - 1;

            //int hash2 = (newVertices[c].x-minX)+(newVertices[c].z-minX)*maxX+newVertices[c].y*maxX*maxZ;
            //int hash2 = Mathfx.ComputeVertexHash (newVertices[c].x,newVertices[c].y,newVertices[c].z);
            if (!hashedVerts.ContainsKey(vertices[newVertices[c]]))
            {
                hashedVerts.Add(vertices[newVertices[c]], c);
                c++;
            }

            for (int x = 0; x < triangles.Length; x++)
            {
                Int3 vertex = vertices[triangles[x]];

                //int hash3 = (vertex.x-minX)+(vertex.z-minX)*maxX+vertex.y*maxX*maxZ;
                //int hash3 = Mathfx.ComputeVertexHash (vertex.x,vertex.y,vertex.z);
                //for (int y=0;y<newVertices.Length;y++) {
                triangles[x] = hashedVerts[vertex];
            }

            /*for (int i=0;i<triangles.Length;i += 3) {
             *
             *      Vector3 offset = Vector3.forward*i*0.01F;
             *      Debug.DrawLine (newVertices[triangles[i]]+offset,newVertices[triangles[i+1]]+offset,Color.blue);
             *      Debug.DrawLine (newVertices[triangles[i+1]]+offset,newVertices[triangles[i+2]]+offset,Color.blue);
             *      Debug.DrawLine (newVertices[triangles[i+2]]+offset,newVertices[triangles[i]]+offset,Color.blue);
             * }*/

            //Debug.Log ("NavMesh - Old vertice count "+vertices.Length+", new vertice count "+c+" "+maxX+" "+maxZ+" "+maxX*maxZ);

            Int3[] totalIntVertices = vertices;
            vertices         = new Int3[c];
            originalVertices = new Vector3[c];
            for (int i = 0; i < c; i++)
            {
                originalVertices[i] = vectorVertices[newVertices[i]];
                vertices[i]         = totalIntVertices[newVertices[i]];        //(Int3)graph.matrix.MultiplyPoint (vectorVertices[i]);
            }

            Node[] nodes = graph.CreateNodes(triangles.Length / 3);           //new Node[triangles.Length/3];
            graph.nodes = nodes;
            for (int i = 0; i < nodes.Length; i++)
            {
                MeshNode node = (MeshNode)nodes[i];                //new MeshNode ();
                node.walkable = true;

                node.position = (vertices[triangles[i * 3]] + vertices[triangles[i * 3 + 1]] + vertices[triangles[i * 3 + 2]]) / 3F;

                node.v1 = triangles[i * 3];
                node.v2 = triangles[i * 3 + 1];
                node.v3 = triangles[i * 3 + 2];

                if (!Polygon.IsClockwise(vertices[node.v1], vertices[node.v2], vertices[node.v3]))
                {
                    //Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
                    //Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.red);
                    //Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.red);

                    int tmp = node.v1;
                    node.v1 = node.v3;
                    node.v3 = tmp;
                }

                if (Polygon.IsColinear(vertices[node.v1], vertices[node.v2], vertices[node.v3]))
                {
                    Debug.DrawLine(vertices[node.v1], vertices[node.v2], Color.red);
                    Debug.DrawLine(vertices[node.v2], vertices[node.v3], Color.red);
                    Debug.DrawLine(vertices[node.v3], vertices[node.v1], Color.red);
                }

                nodes[i] = node;
            }

            List <Node> connections     = new List <Node> ();
            List <int>  connectionCosts = new List <int> ();

            int identicalError = 0;

            for (int i = 0; i < triangles.Length; i += 3)
            {
                connections.Clear();
                connectionCosts.Clear();

                //Int3 indices = new Int3(triangles[i],triangles[i+1],triangles[i+2]);

                Node node = nodes[i / 3];

                for (int x = 0; x < triangles.Length; x += 3)
                {
                    if (x == i)
                    {
                        continue;
                    }

                    int count = 0;
                    if (triangles[x] == triangles[i])
                    {
                        count++;
                    }
                    if (triangles[x + 1] == triangles[i])
                    {
                        count++;
                    }
                    if (triangles[x + 2] == triangles[i])
                    {
                        count++;
                    }
                    if (triangles[x] == triangles[i + 1])
                    {
                        count++;
                    }
                    if (triangles[x + 1] == triangles[i + 1])
                    {
                        count++;
                    }
                    if (triangles[x + 2] == triangles[i + 1])
                    {
                        count++;
                    }
                    if (triangles[x] == triangles[i + 2])
                    {
                        count++;
                    }
                    if (triangles[x + 1] == triangles[i + 2])
                    {
                        count++;
                    }
                    if (triangles[x + 2] == triangles[i + 2])
                    {
                        count++;
                    }

                    if (count >= 3)
                    {
                        identicalError++;
                        Debug.DrawLine(vertices[triangles[x]], vertices[triangles[x + 1]], Color.red);
                        Debug.DrawLine(vertices[triangles[x]], vertices[triangles[x + 2]], Color.red);
                        Debug.DrawLine(vertices[triangles[x + 2]], vertices[triangles[x + 1]], Color.red);
                    }

                    if (count == 2)
                    {
                        Node other = nodes[x / 3];
                        connections.Add(other);
                        connectionCosts.Add(Mathf.RoundToInt((node.position - other.position).magnitude));
                    }
                }

                node.connections     = connections.ToArray();
                node.connectionCosts = connectionCosts.ToArray();
            }

            if (identicalError > 0)
            {
                Debug.LogError("One or more triangles are identical to other triangles, this is not a good thing to have in a navmesh\nIncreasing the scale of the mesh might help\nNumber of triangles with error: " + identicalError + "\n");
            }
            RebuildBBTree(graph);

            //Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
        }
Пример #8
0
 private void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out VInt3[] vertices)
 {
     if (vectorVertices.Length == 0 || triangles.Length == 0)
     {
         originalVertices = vectorVertices;
         vertices = new VInt3[0];
         this.nodes = new TriangleMeshNode[0];
         return;
     }
     vertices = new VInt3[vectorVertices.Length];
     int num = 0;
     for (int i = 0; i < vertices.Length; i++)
     {
         vertices[i] = (VInt3)this.matrix.MultiplyPoint3x4(vectorVertices[i]);
     }
     Dictionary<VInt3, int> dictionary = new Dictionary<VInt3, int>();
     int[] array = new int[vertices.Length];
     for (int j = 0; j < vertices.Length; j++)
     {
         if (!dictionary.ContainsKey(vertices[j]))
         {
             array[num] = j;
             dictionary.Add(vertices[j], num);
             num++;
         }
     }
     for (int k = 0; k < triangles.Length; k++)
     {
         VInt3 vInt = vertices[triangles[k]];
         triangles[k] = dictionary.get_Item(vInt);
     }
     VInt3[] array2 = vertices;
     vertices = new VInt3[num];
     originalVertices = new Vector3[num];
     for (int l = 0; l < num; l++)
     {
         vertices[l] = array2[array[l]];
         originalVertices[l] = vectorVertices[array[l]];
     }
     this.nodes = new TriangleMeshNode[triangles.Length / 3];
     int graphIndex = this.active.astarData.GetGraphIndex(this);
     for (int m = 0; m < this.nodes.Length; m++)
     {
         this.nodes[m] = new TriangleMeshNode(this.active);
         TriangleMeshNode triangleMeshNode = this.nodes[m];
         triangleMeshNode.GraphIndex = (uint)graphIndex;
         triangleMeshNode.Penalty = this.initialPenalty;
         triangleMeshNode.Walkable = true;
         triangleMeshNode.v0 = triangles[m * 3];
         triangleMeshNode.v1 = triangles[m * 3 + 1];
         triangleMeshNode.v2 = triangles[m * 3 + 2];
         if (!Polygon.IsClockwise(vertices[triangleMeshNode.v0], vertices[triangleMeshNode.v1], vertices[triangleMeshNode.v2]))
         {
             int v = triangleMeshNode.v0;
             triangleMeshNode.v0 = triangleMeshNode.v2;
             triangleMeshNode.v2 = v;
         }
         if (Polygon.IsColinear(vertices[triangleMeshNode.v0], vertices[triangleMeshNode.v1], vertices[triangleMeshNode.v2]))
         {
             Debug.DrawLine((Vector3)vertices[triangleMeshNode.v0], (Vector3)vertices[triangleMeshNode.v1], Color.red);
             Debug.DrawLine((Vector3)vertices[triangleMeshNode.v1], (Vector3)vertices[triangleMeshNode.v2], Color.red);
             Debug.DrawLine((Vector3)vertices[triangleMeshNode.v2], (Vector3)vertices[triangleMeshNode.v0], Color.red);
         }
         triangleMeshNode.UpdatePositionFromVertices();
     }
     DictionaryView<VInt2, TriangleMeshNode> dictionaryView = new DictionaryView<VInt2, TriangleMeshNode>();
     int n = 0;
     int num2 = 0;
     while (n < triangles.Length)
     {
         dictionaryView[new VInt2(triangles[n], triangles[n + 1])] = this.nodes[num2];
         dictionaryView[new VInt2(triangles[n + 1], triangles[n + 2])] = this.nodes[num2];
         dictionaryView[new VInt2(triangles[n + 2], triangles[n])] = this.nodes[num2];
         num2++;
         n += 3;
     }
     ListLinqView<MeshNode> listLinqView = new ListLinqView<MeshNode>();
     List<uint> list = new List<uint>();
     int num3 = 0;
     int num4 = 0;
     int num5 = 0;
     while (num4 < triangles.Length)
     {
         listLinqView.Clear();
         list.Clear();
         TriangleMeshNode triangleMeshNode2 = this.nodes[num5];
         for (int num6 = 0; num6 < 3; num6++)
         {
             TriangleMeshNode triangleMeshNode3;
             if (dictionaryView.TryGetValue(new VInt2(triangles[num4 + (num6 + 1) % 3], triangles[num4 + num6]), out triangleMeshNode3))
             {
                 listLinqView.Add(triangleMeshNode3);
                 list.Add((uint)(triangleMeshNode2.position - triangleMeshNode3.position).costMagnitude);
             }
         }
         triangleMeshNode2.connections = listLinqView.ToArray();
         triangleMeshNode2.connectionCosts = list.ToArray();
         num5++;
         num4 += 3;
     }
     if (num3 > 0)
     {
         Debug.LogError("One or more triangles are identical to other triangles, this is not a good thing to have in a navmesh\nIncreasing the scale of the mesh might help\nNumber of triangles with error: " + num3 + "\n");
     }
     NavMeshGraph.RebuildBBTree(this);
 }
Пример #9
0
        public bool RunFunnel(List <VInt3> left, List <VInt3> right, List <VInt3> funnelPath)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }
            if (funnelPath == null)
            {
                throw new ArgumentNullException("funnelPath");
            }
            if (left.get_Count() != right.get_Count())
            {
                throw new ArgumentException("left and right lists must have equal length");
            }
            if (left.get_Count() <= 3)
            {
                return(false);
            }
            while (left.get_Item(1) == left.get_Item(2) && right.get_Item(1) == right.get_Item(2))
            {
                left.RemoveAt(1);
                right.RemoveAt(1);
                if (left.get_Count() <= 3)
                {
                    return(false);
                }
            }
            VInt3 vInt = left.get_Item(2);

            if (vInt == left.get_Item(1))
            {
                vInt = right.get_Item(2);
            }
            while (Polygon.IsColinear(left.get_Item(0), left.get_Item(1), right.get_Item(1)) || Polygon.Left(left.get_Item(1), right.get_Item(1), vInt) == Polygon.Left(left.get_Item(1), right.get_Item(1), left.get_Item(0)))
            {
                left.RemoveAt(1);
                right.RemoveAt(1);
                if (left.get_Count() <= 3)
                {
                    return(false);
                }
                vInt = left.get_Item(2);
                if (vInt == left.get_Item(1))
                {
                    vInt = right.get_Item(2);
                }
            }
            if (!Polygon.IsClockwise(left.get_Item(0), left.get_Item(1), right.get_Item(1)) && !Polygon.IsColinear(left.get_Item(0), left.get_Item(1), right.get_Item(1)))
            {
                List <VInt3> list = left;
                left  = right;
                right = list;
            }
            funnelPath.Add(left.get_Item(0));
            VInt3 vInt2 = left.get_Item(0);
            VInt3 vInt3 = left.get_Item(1);
            VInt3 vInt4 = right.get_Item(1);
            int   num   = 1;
            int   num2  = 1;
            int   i     = 2;

            while (i < left.get_Count())
            {
                if (funnelPath.get_Count() > 2000)
                {
                    Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
                    break;
                }
                VInt3 vInt5 = left.get_Item(i);
                VInt3 vInt6 = right.get_Item(i);
                if (Polygon.TriangleArea2(vInt2, vInt4, vInt6) < 0L)
                {
                    goto IL_27B;
                }
                if (vInt2 == vInt4 || Polygon.TriangleArea2(vInt2, vInt3, vInt6) <= 0L)
                {
                    vInt4 = vInt6;
                    num   = i;
                    goto IL_27B;
                }
                funnelPath.Add(vInt3);
                vInt2 = vInt3;
                int num3 = num2;
                vInt3 = vInt2;
                vInt4 = vInt2;
                num2  = num3;
                num   = num3;
                i     = num3;
IL_270:
                i++;
                continue;
IL_27B:
                if (Polygon.TriangleArea2(vInt2, vInt3, vInt5) > 0L)
                {
                    goto IL_270;
                }
                if (vInt2 == vInt3 || Polygon.TriangleArea2(vInt2, vInt4, vInt5) >= 0L)
                {
                    vInt3 = vInt5;
                    num2  = i;
                    goto IL_270;
                }
                funnelPath.Add(vInt4);
                vInt2 = vInt4;
                num3  = num;
                vInt3 = vInt2;
                vInt4 = vInt2;
                num2  = num3;
                num   = num3;
                i     = num3;
                goto IL_270;
            }
            funnelPath.Add(left.get_Item(left.get_Count() - 1));
            return(true);
        }
Пример #10
0
        public bool FindNextCorners(Vector3 origin, int startIndex, List <Vector3> funnelPath, int numCorners, out bool lastCorner)
        {
            lastCorner = false;
            if (this.left == null)
            {
                throw new Exception("left list is null");
            }
            if (this.right == null)
            {
                throw new Exception("right list is null");
            }
            if (funnelPath == null)
            {
                throw new ArgumentNullException("funnelPath");
            }
            if (this.left.Count != this.right.Count)
            {
                throw new ArgumentException("left and right lists must have equal length");
            }
            int count = this.left.Count;

            if (count == 0)
            {
                throw new ArgumentException("no diagonals");
            }
            if (count - startIndex < 3)
            {
                funnelPath.Add(this.left[count - 1]);
                lastCorner = true;
                return(true);
            }
            while (this.left[startIndex + 1] == this.left[startIndex + 2] && this.right[startIndex + 1] == this.right[startIndex + 2])
            {
                startIndex++;
                if (count - startIndex <= 3)
                {
                    return(false);
                }
            }
            Vector3 vector = this.left[startIndex + 2];

            if (vector == this.left[startIndex + 1])
            {
                vector = this.right[startIndex + 2];
            }
            while (Polygon.IsColinear(origin, this.left[startIndex + 1], this.right[startIndex + 1]) || Polygon.Left(this.left[startIndex + 1], this.right[startIndex + 1], vector) == Polygon.Left(this.left[startIndex + 1], this.right[startIndex + 1], origin))
            {
                startIndex++;
                if (count - startIndex < 3)
                {
                    funnelPath.Add(this.left[count - 1]);
                    lastCorner = true;
                    return(true);
                }
                vector = this.left[startIndex + 2];
                if (vector == this.left[startIndex + 1])
                {
                    vector = this.right[startIndex + 2];
                }
            }
            Vector3 vector2 = origin;
            Vector3 vector3 = this.left[startIndex + 1];
            Vector3 vector4 = this.right[startIndex + 1];
            int     num     = startIndex + 1;
            int     num2    = startIndex + 1;
            int     i       = startIndex + 2;

            while (i < count)
            {
                if (funnelPath.Count >= numCorners)
                {
                    return(true);
                }
                if (funnelPath.Count > 2000)
                {
                    Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
                    break;
                }
                Vector3 vector5 = this.left[i];
                Vector3 vector6 = this.right[i];
                if (Polygon.TriangleArea2(vector2, vector4, vector6) < 0f)
                {
                    goto IL_2FB;
                }
                if (vector2 == vector4 || Polygon.TriangleArea2(vector2, vector3, vector6) <= 0f)
                {
                    vector4 = vector6;
                    num     = i;
                    goto IL_2FB;
                }
                funnelPath.Add(vector3);
                vector2 = vector3;
                int num3 = num2;
                vector3 = vector2;
                vector4 = vector2;
                num2    = num3;
                num     = num3;
                i       = num3;
IL_35F:
                i++;
                continue;
IL_2FB:
                if (Polygon.TriangleArea2(vector2, vector3, vector5) > 0f)
                {
                    goto IL_35F;
                }
                if (vector2 == vector3 || Polygon.TriangleArea2(vector2, vector4, vector5) >= 0f)
                {
                    vector3 = vector5;
                    num2    = i;
                    goto IL_35F;
                }
                funnelPath.Add(vector4);
                vector2 = vector4;
                num3    = num;
                vector3 = vector2;
                vector4 = vector2;
                num2    = num3;
                num     = num3;
                i       = num3;
                goto IL_35F;
            }
            lastCorner = true;
            funnelPath.Add(this.left[count - 1]);
            return(true);
        }
Пример #11
0
        // Token: 0x060006B1 RID: 1713 RVA: 0x000424C4 File Offset: 0x000408C4
        public bool RunFunnel(List <Vector3> left, List <Vector3> right, List <Vector3> funnelPath)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }
            if (funnelPath == null)
            {
                throw new ArgumentNullException("funnelPath");
            }
            if (left.Count != right.Count)
            {
                throw new ArgumentException("left and right lists must have equal length");
            }
            if (left.Count <= 3)
            {
                return(false);
            }
            while (left[1] == left[2] && right[1] == right[2])
            {
                left.RemoveAt(1);
                right.RemoveAt(1);
                if (left.Count <= 3)
                {
                    return(false);
                }
            }
            Vector3 vector = left[2];

            if (vector == left[1])
            {
                vector = right[2];
            }
            while (Polygon.IsColinear(left[0], left[1], right[1]) || Polygon.Left(left[1], right[1], vector) == Polygon.Left(left[1], right[1], left[0]))
            {
                left.RemoveAt(1);
                right.RemoveAt(1);
                if (left.Count <= 3)
                {
                    return(false);
                }
                vector = left[2];
                if (vector == left[1])
                {
                    vector = right[2];
                }
            }
            if (!Polygon.IsClockwise(left[0], left[1], right[1]) && !Polygon.IsColinear(left[0], left[1], right[1]))
            {
                List <Vector3> list = left;
                left  = right;
                right = list;
            }
            funnelPath.Add(left[0]);
            Vector3 vector2 = left[0];
            Vector3 vector3 = left[1];
            Vector3 vector4 = right[1];
            int     num     = 1;
            int     num2    = 1;
            int     i       = 2;

            while (i < left.Count)
            {
                if (funnelPath.Count > 2000)
                {
                    Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
                    break;
                }
                Vector3 vector5 = left[i];
                Vector3 vector6 = right[i];
                if (Polygon.TriangleArea2(vector2, vector4, vector6) < 0f)
                {
                    goto IL_279;
                }
                if (vector2 == vector4 || Polygon.TriangleArea2(vector2, vector3, vector6) <= 0f)
                {
                    vector4 = vector6;
                    num     = i;
                    goto IL_279;
                }
                funnelPath.Add(vector3);
                vector2 = vector3;
                int num3 = num2;
                vector3 = vector2;
                vector4 = vector2;
                num2    = num3;
                num     = num3;
                i       = num3;
IL_2DD:
                i++;
                continue;
IL_279:
                if (Polygon.TriangleArea2(vector2, vector3, vector5) > 0f)
                {
                    goto IL_2DD;
                }
                if (vector2 == vector3 || Polygon.TriangleArea2(vector2, vector4, vector5) >= 0f)
                {
                    vector3 = vector5;
                    num2    = i;
                    goto IL_2DD;
                }
                funnelPath.Add(vector4);
                vector2 = vector4;
                num3    = num;
                vector3 = vector2;
                vector4 = vector2;
                num2    = num3;
                num     = num3;
                i       = num3;
                goto IL_2DD;
            }
            funnelPath.Add(left[left.Count - 1]);
            return(true);
        }
Пример #12
0
        public List <Vector3> SmoothOffsetSimple(List <Vector3> path)
        {
            if (path.Count <= 2 || this.iterations <= 0)
            {
                return(path);
            }
            if (this.iterations > 12)
            {
                Debug.LogWarning("A very high iteration count was passed, won't let this one through");
                return(path);
            }
            int            num  = (path.Count - 2) * (int)Mathf.Pow(2f, (float)this.iterations) + 2;
            List <Vector3> list = ListPool <Vector3> .Claim(num);

            List <Vector3> list2 = ListPool <Vector3> .Claim(num);

            for (int i = 0; i < num; i++)
            {
                list.Add(Vector3.zero);
                list2.Add(Vector3.zero);
            }
            for (int j = 0; j < path.Count; j++)
            {
                list[j] = path[j];
            }
            for (int k = 0; k < this.iterations; k++)
            {
                int            num2  = (path.Count - 2) * (int)Mathf.Pow(2f, (float)k) + 2;
                List <Vector3> list3 = list;
                list  = list2;
                list2 = list3;
                for (int l = 0; l < num2 - 1; l++)
                {
                    Vector3 vector     = list2[l];
                    Vector3 vector2    = list2[l + 1];
                    Vector3 normalized = Vector3.Cross(vector2 - vector, Vector3.up).normalized;
                    bool    flag       = false;
                    bool    flag2      = false;
                    bool    flag3      = false;
                    bool    flag4      = false;
                    if (l != 0 && !Polygon.IsColinear(vector, vector2, list2[l - 1]))
                    {
                        flag3 = true;
                        flag  = Polygon.Left(vector, vector2, list2[l - 1]);
                    }
                    if (l < num2 - 1 && !Polygon.IsColinear(vector, vector2, list2[l + 2]))
                    {
                        flag4 = true;
                        flag2 = Polygon.Left(vector, vector2, list2[l + 2]);
                    }
                    if (flag3)
                    {
                        list[l * 2] = vector + ((!flag) ? (-normalized * this.offset * 1f) : (normalized * this.offset * 1f));
                    }
                    else
                    {
                        list[l * 2] = vector;
                    }
                    if (flag4)
                    {
                        list[l * 2 + 1] = vector2 + ((!flag2) ? (-normalized * this.offset * 1f) : (normalized * this.offset * 1f));
                    }
                    else
                    {
                        list[l * 2 + 1] = vector2;
                    }
                }
                list[(path.Count - 2) * (int)Mathf.Pow(2f, (float)(k + 1)) + 2 - 1] = list2[num2 - 1];
            }
            ListPool <Vector3> .Release(list2);

            return(list);
        }
Пример #13
0
        public bool FindNextCorners(Vector3 origin, int startIndex, List <Vector3> funnelPath, int numCorners, out bool lastCorner)
        {
            lastCorner = false;

            if (left == null)
            {
                throw new System.Exception("left list is null");
            }
            if (right == null)
            {
                throw new System.Exception("right list is null");
            }
            if (funnelPath == null)
            {
                throw new System.ArgumentNullException("funnelPath");
            }

            if (left.Count != right.Count)
            {
                throw new System.ArgumentException("left and right lists must have equal length");
            }

            int diagonalCount = left.Count;

            if (diagonalCount == 0)
            {
                throw new System.ArgumentException("no diagonals");
            }

            if (diagonalCount - startIndex < 3)
            {
                //Direct path
                funnelPath.Add(left[diagonalCount - 1]);
                lastCorner = true;
                return(true);
            }

                        #if ASTARDEBUG
            for (int i = startIndex; i < left.Count - 1; i++)
            {
                Debug.DrawLine(left[i], left[i + 1], Color.red);
                Debug.DrawLine(right[i], right[i + 1], Color.magenta);
                Debug.DrawRay(right[i], Vector3.up, Color.magenta);
            }
            for (int i = 0; i < left.Count; i++)
            {
                Debug.DrawLine(right[i], left[i], Color.cyan);
            }
                #endif

            //Remove identical vertices
            while (left[startIndex + 1] == left[startIndex + 2] && right[startIndex + 1] == right[startIndex + 2])
            {
                //System.Console.WriteLine ("Removing identical left and right");
                //left.RemoveAt (1);
                //right.RemoveAt (1);
                startIndex++;

                if (diagonalCount - startIndex <= 3)
                {
                    return(false);
                }
            }

            Vector3 swPoint = left[startIndex + 2];
            if (swPoint == left[startIndex + 1])
            {
                swPoint = right[startIndex + 2];
            }


            //Test
            while (Polygon.IsColinear(origin, left[startIndex + 1], right[startIndex + 1]) || Polygon.Left(left[startIndex + 1], right[startIndex + 1], swPoint) == Polygon.Left(left[startIndex + 1], right[startIndex + 1], origin))
            {
        #if ASTARDEBUG
                Debug.DrawLine(left[startIndex + 1], right[startIndex + 1], new Color(0, 0, 0, 0.5F));
                Debug.DrawLine(origin, swPoint, new Color(0, 0, 0, 0.5F));
        #endif
                //left.RemoveAt (1);
                //right.RemoveAt (1);
                startIndex++;

                if (diagonalCount - startIndex < 3)
                {
                    //Debug.Log ("#2 " + left.Count + " - " + startIndex + " = " + (left.Count-startIndex));
                    //Direct path
                    funnelPath.Add(left[diagonalCount - 1]);
                    lastCorner = true;
                    return(true);
                }

                swPoint = left[startIndex + 2];
                if (swPoint == left[startIndex + 1])
                {
                    swPoint = right[startIndex + 2];
                }
            }


            //funnelPath.Add (origin);

            Vector3 portalApex  = origin;
            Vector3 portalLeft  = left[startIndex + 1];
            Vector3 portalRight = right[startIndex + 1];

            int apexIndex  = startIndex + 0;
            int rightIndex = startIndex + 1;
            int leftIndex  = startIndex + 1;

            for (int i = startIndex + 2; i < diagonalCount; i++)
            {
                if (funnelPath.Count >= numCorners)
                {
                    return(true);
                }

                if (funnelPath.Count > 2000)
                {
                    Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
                    break;
                }

                Vector3 pLeft  = left[i];
                Vector3 pRight = right[i];

                /*Debug.DrawLine (portalApex,portalLeft,Color.red);
                 * Debug.DrawLine (portalApex,portalRight,Color.yellow);
                 * Debug.DrawLine (portalApex,left,Color.cyan);
                 * Debug.DrawLine (portalApex,right,Color.cyan);*/

                if (Polygon.TriangleArea2(portalApex, portalRight, pRight) >= 0)
                {
                    if (portalApex == portalRight || Polygon.TriangleArea2(portalApex, portalLeft, pRight) <= 0)
                    {
                        portalRight = pRight;
                        rightIndex  = i;
                    }
                    else
                    {
                        funnelPath.Add(portalLeft);
                        portalApex = portalLeft;
                        apexIndex  = leftIndex;

                        portalLeft  = portalApex;
                        portalRight = portalApex;

                        leftIndex  = apexIndex;
                        rightIndex = apexIndex;

                        i = apexIndex;

                        continue;
                    }
                }

                if (Polygon.TriangleArea2(portalApex, portalLeft, pLeft) <= 0)
                {
                    if (portalApex == portalLeft || Polygon.TriangleArea2(portalApex, portalRight, pLeft) >= 0)
                    {
                        portalLeft = pLeft;
                        leftIndex  = i;
                    }
                    else
                    {
                        funnelPath.Add(portalRight);
                        portalApex = portalRight;
                        apexIndex  = rightIndex;

                        portalLeft  = portalApex;
                        portalRight = portalApex;

                        leftIndex  = apexIndex;
                        rightIndex = apexIndex;

                        i = apexIndex;

                        continue;
                    }
                }
            }

            lastCorner = true;
            funnelPath.Add(left[diagonalCount - 1]);

            return(true);
        }
Пример #14
0
 private void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out VInt3[] vertices)
 {
     if ((vectorVertices.Length == 0) || (triangles.Length == 0))
     {
         originalVertices = vectorVertices;
         vertices         = new VInt3[0];
         this.nodes       = new TriangleMeshNode[0];
     }
     else
     {
         vertices = new VInt3[vectorVertices.Length];
         int index = 0;
         for (int i = 0; i < vertices.Length; i++)
         {
             vertices[i] = (VInt3)this.matrix.MultiplyPoint3x4(vectorVertices[i]);
         }
         Dictionary <VInt3, int> dictionary = new Dictionary <VInt3, int>();
         int[] numArray = new int[vertices.Length];
         for (int j = 0; j < vertices.Length; j++)
         {
             if (!dictionary.ContainsKey(vertices[j]))
             {
                 numArray[index] = j;
                 dictionary.Add(vertices[j], index);
                 index++;
             }
         }
         for (int k = 0; k < triangles.Length; k++)
         {
             VInt3 num5 = vertices[triangles[k]];
             triangles[k] = dictionary[num5];
         }
         VInt3[] numArray2 = vertices;
         vertices         = new VInt3[index];
         originalVertices = new Vector3[index];
         for (int m = 0; m < index; m++)
         {
             vertices[m]         = numArray2[numArray[m]];
             originalVertices[m] = vectorVertices[numArray[m]];
         }
         this.nodes = new TriangleMeshNode[triangles.Length / 3];
         int graphIndex = base.active.astarData.GetGraphIndex(this);
         for (int n = 0; n < this.nodes.Length; n++)
         {
             this.nodes[n] = new TriangleMeshNode(base.active);
             TriangleMeshNode node = this.nodes[n];
             node.GraphIndex = (uint)graphIndex;
             node.Penalty    = base.initialPenalty;
             node.Walkable   = true;
             node.v0         = triangles[n * 3];
             node.v1         = triangles[(n * 3) + 1];
             node.v2         = triangles[(n * 3) + 2];
             if (!Polygon.IsClockwise(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
             {
                 int num9 = node.v0;
                 node.v0 = node.v2;
                 node.v2 = num9;
             }
             if (Polygon.IsColinear(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
             {
                 Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.red);
                 Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.red);
                 Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.red);
             }
             node.UpdatePositionFromVertices();
         }
         DictionaryView <VInt2, TriangleMeshNode> view = new DictionaryView <VInt2, TriangleMeshNode>();
         int num10 = 0;
         int num11 = 0;
         while (num10 < triangles.Length)
         {
             view[new VInt2(triangles[num10], triangles[num10 + 1])]     = this.nodes[num11];
             view[new VInt2(triangles[num10 + 1], triangles[num10 + 2])] = this.nodes[num11];
             view[new VInt2(triangles[num10 + 2], triangles[num10])]     = this.nodes[num11];
             num11++;
             num10 += 3;
         }
         ListLinqView <MeshNode> view2 = new ListLinqView <MeshNode>();
         List <uint>             list  = new List <uint>();
         int num12 = 0;
         int num13 = 0;
         int num14 = 0;
         while (num13 < triangles.Length)
         {
             view2.Clear();
             list.Clear();
             TriangleMeshNode node2 = this.nodes[num14];
             for (int num15 = 0; num15 < 3; num15++)
             {
                 TriangleMeshNode node3;
                 if (view.TryGetValue(new VInt2(triangles[num13 + ((num15 + 1) % 3)], triangles[num13 + num15]), out node3))
                 {
                     view2.Add(node3);
                     VInt3 num16 = node2.position - node3.position;
                     list.Add((uint)num16.costMagnitude);
                 }
             }
             node2.connections     = view2.ToArray();
             node2.connectionCosts = list.ToArray();
             num14++;
             num13 += 3;
         }
         if (num12 > 0)
         {
             Debug.LogError("One or more triangles are identical to other triangles, this is not a good thing to have in a navmesh\nIncreasing the scale of the mesh might help\nNumber of triangles with error: " + num12 + "\n");
         }
         RebuildBBTree(this);
     }
 }
Пример #15
0
        /** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */
        void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices)
        {
            Profiler.BeginSample("Init");

            if (vectorVertices.Length == 0 || triangles.Length == 0)
            {
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                //graph.CreateNodes (0);
                nodes = new TriangleMeshNode[0];
                return;
            }

            vertices = new Int3[vectorVertices.Length];

            //Backup the original vertices
            //for (int i=0;i<vectorVertices.Length;i++) {
            //	vectorVertices[i] = graph.matrix.MultiplyPoint (vectorVertices[i]);
            //}

            int c = 0;

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = (Int3)matrix.MultiplyPoint3x4(vectorVertices[i]);
            }

            Dictionary <Int3, int> hashedVerts = new Dictionary <Int3, int> ();

            int[] newVertices = new int[vertices.Length];

            Profiler.EndSample();
            Profiler.BeginSample("Hashing");

            for (int i = 0; i < vertices.Length; i++)
            {
                if (!hashedVerts.ContainsKey(vertices[i]))
                {
                    newVertices[c] = i;
                    hashedVerts.Add(vertices[i], c);
                    c++;
                }                // else {
                //Debug.Log ("Hash Duplicate "+hash+" "+vertices[i].ToString ());
                //}
            }

            /*newVertices[c] = vertices.Length-1;
             *
             * if (!hashedVerts.ContainsKey (vertices[newVertices[c]])) {
             *
             *      hashedVerts.Add (vertices[newVertices[c]], c);
             *      c++;
             * }*/

            for (int x = 0; x < triangles.Length; x++)
            {
                Int3 vertex = vertices[triangles[x]];

                triangles[x] = hashedVerts[vertex];
            }

            /*for (int i=0;i<triangles.Length;i += 3) {
             *
             *      Vector3 offset = Vector3.forward*i*0.01F;
             *      Debug.DrawLine (newVertices[triangles[i]]+offset,newVertices[triangles[i+1]]+offset,Color.blue);
             *      Debug.DrawLine (newVertices[triangles[i+1]]+offset,newVertices[triangles[i+2]]+offset,Color.blue);
             *      Debug.DrawLine (newVertices[triangles[i+2]]+offset,newVertices[triangles[i]]+offset,Color.blue);
             * }*/

            Int3[] totalIntVertices = vertices;
            vertices         = new Int3[c];
            originalVertices = new Vector3[c];
            for (int i = 0; i < c; i++)
            {
                vertices[i]         = totalIntVertices[newVertices[i]];        //(Int3)graph.matrix.MultiplyPoint (vectorVertices[i]);
                originalVertices[i] = (Vector3)vectorVertices[newVertices[i]]; //vectorVertices[newVertices[i]];
            }

            Profiler.EndSample();
            Profiler.BeginSample("Constructing Nodes");

            //graph.CreateNodes (triangles.Length/3);//new Node[triangles.Length/3];
            nodes = new TriangleMeshNode[triangles.Length / 3];

            int graphIndex = active.astarData.GetGraphIndex(this);

            // Does not have to set this, it is set in ScanInternal
            //TriangleMeshNode.SetNavmeshHolder ((int)graphIndex,this);

            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i] = new TriangleMeshNode(active);
                TriangleMeshNode node = nodes[i];                //new MeshNode ();

                node.GraphIndex = (uint)graphIndex;
                node.Penalty    = initialPenalty;
                node.Walkable   = true;


                node.v0 = triangles[i * 3];
                node.v1 = triangles[i * 3 + 1];
                node.v2 = triangles[i * 3 + 2];

                if (!Polygon.IsClockwise(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
                {
                    //Debug.DrawLine (vertices[node.v0],vertices[node.v1],Color.red);
                    //Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
                    //Debug.DrawLine (vertices[node.v2],vertices[node.v0],Color.red);

                    int tmp = node.v0;
                    node.v0 = node.v2;
                    node.v2 = tmp;
                }

                if (Polygon.IsColinear(vertices[node.v0], vertices[node.v1], vertices[node.v2]))
                {
                    Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.red);
                    Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.red);
                    Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.red);
                }

                // Make sure position is correctly set
                node.UpdatePositionFromVertices();
            }

            Profiler.EndSample();

            Dictionary <Int2, TriangleMeshNode> sides = new Dictionary <Int2, TriangleMeshNode>();

            for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
            {
                sides[new Int2(triangles[i + 0], triangles[i + 1])] = nodes[j];
                sides[new Int2(triangles[i + 1], triangles[i + 2])] = nodes[j];
                sides[new Int2(triangles[i + 2], triangles[i + 0])] = nodes[j];
            }

            Profiler.BeginSample("Connecting Nodes");

            List <MeshNode> connections     = new List <MeshNode> ();
            List <uint>     connectionCosts = new List <uint> ();

            int identicalError = 0;

            for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
            {
                connections.Clear();
                connectionCosts.Clear();

                //Int3 indices = new Int3(triangles[i],triangles[i+1],triangles[i+2]);

                TriangleMeshNode node = nodes[j];

                for (int q = 0; q < 3; q++)
                {
                    TriangleMeshNode other;
                    if (sides.TryGetValue(new Int2(triangles[i + ((q + 1) % 3)], triangles[i + q]), out other))
                    {
                        connections.Add(other);
                        connectionCosts.Add((uint)(node.position - other.position).costMagnitude);
                    }
                }

                node.connections     = connections.ToArray();
                node.connectionCosts = connectionCosts.ToArray();
            }

            if (identicalError > 0)
            {
                Debug.LogError("One or more triangles are identical to other triangles, this is not a good thing to have in a navmesh\nIncreasing the scale of the mesh might help\nNumber of triangles with error: " + identicalError + "\n");
            }

            Profiler.EndSample();
            Profiler.BeginSample("Rebuilding BBTree");

            RebuildBBTree(this);

            Profiler.EndSample();

            //Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
        }
Пример #16
0
        /** Calculate a funnel path from the \a left and \a right portal lists.
         * The result will be appended to \a funnelPath
         */
        public static bool RunFunnel(List <Vector3> left, List <Vector3> right, List <Vector3> funnelPath)
        {
            if (left == null)
            {
                throw new System.ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new System.ArgumentNullException("right");
            }
            if (funnelPath == null)
            {
                throw new System.ArgumentNullException("funnelPath");
            }

            if (left.Count != right.Count)
            {
                throw new System.ArgumentException("left and right lists must have equal length");
            }

            if (left.Count <= 3)
            {
                return(false);
            }

            //Remove identical vertices
            while (left[1] == left[2] && right[1] == right[2])
            {
                //System.Console.WriteLine ("Removing identical left and right");
                left.RemoveAt(1);
                right.RemoveAt(1);

                if (left.Count <= 3)
                {
                    return(false);
                }
            }

            Vector3 swPoint = left[2];

            if (swPoint == left[1])
            {
                swPoint = right[2];
            }

            //Test
            while (Polygon.IsColinear(left[0], left[1], right[1]) || Polygon.Left(left[1], right[1], swPoint) == Polygon.Left(left[1], right[1], left[0]))
            {
                left.RemoveAt(1);
                right.RemoveAt(1);

                if (left.Count <= 3)
                {
                    return(false);
                }

                swPoint = left[2];
                if (swPoint == left[1])
                {
                    swPoint = right[2];
                }
            }

            //Switch left and right to really be on the "left" and "right" sides
            if (!Polygon.IsClockwise(left[0], left[1], right[1]) && !Polygon.IsColinear(left[0], left[1], right[1]))
            {
                //System.Console.WriteLine ("Wrong Side 2");
                List <Vector3> tmp = left;
                left  = right;
                right = tmp;
            }


            funnelPath.Add(left[0]);

            Vector3 portalApex  = left[0];
            Vector3 portalLeft  = left[1];
            Vector3 portalRight = right[1];

            int apexIndex  = 0;
            int rightIndex = 1;
            int leftIndex  = 1;

            for (int i = 2; i < left.Count; i++)
            {
                if (funnelPath.Count > 2000)
                {
                    Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
                    break;
                }

                Vector3 pLeft  = left[i];
                Vector3 pRight = right[i];

                /*Debug.DrawLine (portalApex,portalLeft,Color.red);
                 * Debug.DrawLine (portalApex,portalRight,Color.yellow);
                 * Debug.DrawLine (portalApex,left,Color.cyan);
                 * Debug.DrawLine (portalApex,right,Color.cyan);*/

                if (Polygon.TriangleArea2(portalApex, portalRight, pRight) >= 0)
                {
                    if (portalApex == portalRight || Polygon.TriangleArea2(portalApex, portalLeft, pRight) <= 0)
                    {
                        portalRight = pRight;
                        rightIndex  = i;
                    }
                    else
                    {
                        funnelPath.Add(portalLeft);
                        portalApex = portalLeft;
                        apexIndex  = leftIndex;

                        portalLeft  = portalApex;
                        portalRight = portalApex;

                        leftIndex  = apexIndex;
                        rightIndex = apexIndex;

                        i = apexIndex;

                        continue;
                    }
                }

                if (Polygon.TriangleArea2(portalApex, portalLeft, pLeft) <= 0)
                {
                    if (portalApex == portalLeft || Polygon.TriangleArea2(portalApex, portalRight, pLeft) >= 0)
                    {
                        portalLeft = pLeft;
                        leftIndex  = i;
                    }
                    else
                    {
                        funnelPath.Add(portalRight);
                        portalApex = portalRight;
                        apexIndex  = rightIndex;

                        portalLeft  = portalApex;
                        portalRight = portalApex;

                        leftIndex  = apexIndex;
                        rightIndex = apexIndex;

                        i = apexIndex;

                        continue;
                    }
                }
            }

            funnelPath.Add(left[left.Count - 1]);
            return(true);
        }
Пример #17
0
        public List <Vector3> SmoothOffsetSimple(List <Vector3> path)
        {
            if (path.Count <= 2 || iterations <= 0)
            {
                return(path);
            }

            if (iterations > 12)
            {
                Debug.LogWarning("A very high iteration count was passed, won't let this one through");
                return(path);
            }

            int maxLength = (path.Count - 2) * (int)Mathf.Pow(2, iterations) + 2;

            List <Vector3> subdivided = ListPool <Vector3> .Claim(maxLength);

            //new Vector3[(path.Length-2)*(int)Mathf.Pow(2,iterations)+2];
            List <Vector3> subdivided2 = ListPool <Vector3> .Claim(maxLength);

            //new Vector3[(path.Length-2)*(int)Mathf.Pow(2,iterations)+2];

            for (int i = 0; i < maxLength; i++)
            {
                subdivided.Add(Vector3.zero); subdivided2.Add(Vector3.zero);
            }

            for (int i = 0; i < path.Count; i++)
            {
                subdivided[i] = path[i];
            }

            for (int iteration = 0; iteration < iterations; iteration++)
            {
                int currentPathLength = (path.Count - 2) * (int)Mathf.Pow(2, iteration) + 2;

                //Switch the arrays
                List <Vector3> tmp = subdivided;
                subdivided  = subdivided2;
                subdivided2 = tmp;

                float nextMultiplier = 1F;

                for (int i = 0; i < currentPathLength - 1; i++)
                {
                    Vector3 current = subdivided2[i];
                    Vector3 next    = subdivided2[i + 1];

                    Vector3 normal = Vector3.Cross(next - current, Vector3.up);
                    normal = normal.normalized;

                    //This didn't work very well, made the path jaggy

                    /*Vector3 dir = next-current;
                     * dir *= strength*0.5F;
                     * current += dir;
                     * next -= dir;*/

                    bool firstRight  = false;
                    bool secondRight = false;
                    bool setFirst    = false;
                    bool setSecond   = false;
                    if (i != 0 && !Polygon.IsColinear(current, next, subdivided2[i - 1]))
                    {
                        setFirst   = true;
                        firstRight = Polygon.Left(current, next, subdivided2[i - 1]);
                    }
                    if (i < currentPathLength - 1 && !Polygon.IsColinear(current, next, subdivided2[i + 2]))
                    {
                        setSecond   = true;
                        secondRight = Polygon.Left(current, next, subdivided2[i + 2]);
                    }

                    if (setFirst)
                    {
                        subdivided[i * 2] = current + (firstRight ? normal * offset * nextMultiplier : -normal * offset * nextMultiplier);
                    }
                    else
                    {
                        subdivided[i * 2] = current;
                    }

                    //Didn't work very well

                    /*if (setFirst && setSecond) {
                     *      if (firstRight != secondRight) {
                     *              nextMultiplier = 0.5F;
                     *      } else {
                     *              nextMultiplier = 1F;
                     *      }
                     * }*/

                    if (setSecond)
                    {
                        subdivided[i * 2 + 1] = next + (secondRight ? normal * offset * nextMultiplier : -normal * offset * nextMultiplier);
                    }
                    else
                    {
                        subdivided[i * 2 + 1] = next;
                    }
                }

                subdivided[(path.Count - 2) * (int)Mathf.Pow(2, iteration + 1) + 2 - 1] = subdivided2[currentPathLength - 1];
            }


            ListPool <Vector3> .Release(subdivided2);

            return(subdivided);
        }
Пример #18
0
        public bool RunFunnel(List <VInt3> left, List <VInt3> right, List <VInt3> funnelPath)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }
            if (funnelPath == null)
            {
                throw new ArgumentNullException("funnelPath");
            }
            if (left.Count != right.Count)
            {
                throw new ArgumentException("left and right lists must have equal length");
            }
            if (left.Count <= 3)
            {
                return(false);
            }
            while ((left[1] == left[2]) && (right[1] == right[2]))
            {
                left.RemoveAt(1);
                right.RemoveAt(1);
                if (left.Count <= 3)
                {
                    return(false);
                }
            }
            VInt3 c = left[2];

            if (c == left[1])
            {
                c = right[2];
            }
            while (Polygon.IsColinear(left[0], left[1], right[1]) || (Polygon.Left(left[1], right[1], c) == Polygon.Left(left[1], right[1], left[0])))
            {
                left.RemoveAt(1);
                right.RemoveAt(1);
                if (left.Count <= 3)
                {
                    return(false);
                }
                c = left[2];
                if (c == left[1])
                {
                    c = right[2];
                }
            }
            if (!Polygon.IsClockwise(left[0], left[1], right[1]) && !Polygon.IsColinear(left[0], left[1], right[1]))
            {
                List <VInt3> list = left;
                left  = right;
                right = list;
            }
            funnelPath.Add(left[0]);
            VInt3 a    = left[0];
            VInt3 b    = left[1];
            VInt3 num4 = right[1];
            int   num5 = 0;
            int   num6 = 1;
            int   num7 = 1;

            for (int i = 2; i < left.Count; i++)
            {
                if (funnelPath.Count > 0x7d0)
                {
                    Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
                    break;
                }
                VInt3 num9  = left[i];
                VInt3 num10 = right[i];
                if (Polygon.TriangleArea2(a, num4, num10) >= 0L)
                {
                    if ((a == num4) || (Polygon.TriangleArea2(a, b, num10) <= 0L))
                    {
                        num4 = num10;
                        num6 = i;
                    }
                    else
                    {
                        funnelPath.Add(b);
                        a    = b;
                        num5 = num7;
                        b    = a;
                        num4 = a;
                        num7 = num5;
                        num6 = num5;
                        i    = num5;
                        continue;
                    }
                }
                if (Polygon.TriangleArea2(a, b, num9) <= 0L)
                {
                    if ((a == b) || (Polygon.TriangleArea2(a, num4, num9) >= 0L))
                    {
                        b    = num9;
                        num7 = i;
                    }
                    else
                    {
                        funnelPath.Add(num4);
                        a    = num4;
                        num5 = num6;
                        b    = a;
                        num4 = a;
                        num7 = num5;
                        num6 = num5;
                        i    = num5;
                    }
                }
            }
            funnelPath.Add(left[left.Count - 1]);
            return(true);
        }