TriangleArea2() public static method

public static TriangleArea2 ( Vector3 a, Vector3 b, Vector3 c ) : float
a Vector3
b Vector3
c Vector3
return float
Ejemplo n.º 1
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");
        }
Ejemplo n.º 2
0
        /** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other.
         * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
         * For other node types, only the positions of the nodes will be used.
         *
         * clearanceRadius will be reduced if no valid points can be found.
         */
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0)
        {
            if (nodes == null)
            {
                throw new System.ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("no nodes passed");
            }

            var rnd = new System.Random();

            List <Vector3> pts = ListPool <Vector3> .Claim(count);

            // Square
            clearanceRadius *= clearanceRadius;

            if (nodes[0] is TriangleMeshNode
#if !ASTAR_NO_GRID_GRAPH
                || nodes[0] is GridNode
#endif
                )
            {
                //Assume all nodes are triangle nodes or grid nodes

                List <float> accs = ListPool <float> .Claim(nodes.Count);

                float tot = 0;

                for (int i = 0; i < nodes.Count; i++)
                {
                    var tnode = nodes[i] as TriangleMeshNode;
                    if (tnode != null)
                    {
                        /** \bug Doesn't this need to be divided by 2? */
                        float a = System.Math.Abs(Polygon.TriangleArea2(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2)));
                        tot += a;
                        accs.Add(tot);
                    }
#if !ASTAR_NO_GRID_GRAPH
                    else
                    {
                        var gnode = nodes[i] as GridNode;

                        if (gnode != null)
                        {
                            GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex);
                            float     a  = gg.nodeSize * gg.nodeSize;
                            tot += a;
                            accs.Add(tot);
                        }
                        else
                        {
                            accs.Add(tot);
                        }
                    }
#endif
                }

                for (int i = 0; i < count; i++)
                {
                    //Pick point
                    int  testCount = 0;
                    int  testLimit = 10;
                    bool worked    = false;

                    while (!worked)
                    {
                        worked = true;

                        //If no valid points can be found, progressively lower the clearance radius until such a point is found
                        if (testCount >= testLimit)
                        {
                            clearanceRadius *= 0.8f;
                            testLimit       += 10;
                            if (testLimit > 100)
                            {
                                clearanceRadius = 0;
                            }
                        }

                        float tg = (float)rnd.NextDouble() * tot;
                        int   v  = accs.BinarySearch(tg);
                        if (v < 0)
                        {
                            v = ~v;
                        }

                        if (v >= nodes.Count)
                        {
                            // This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic.
                            worked = false;
                            continue;
                        }

                        var node = nodes[v] as TriangleMeshNode;

                        Vector3 p;

                        if (node != null)
                        {
                            // Find a random point inside the triangle
                            float v1;
                            float v2;
                            do
                            {
                                v1 = (float)rnd.NextDouble();
                                v2 = (float)rnd.NextDouble();
                            } while (v1 + v2 > 1);

                            p = ((Vector3)(node.GetVertex(1) - node.GetVertex(0))) * v1 + ((Vector3)(node.GetVertex(2) - node.GetVertex(0))) * v2 + (Vector3)node.GetVertex(0);
                        }
                        else
                        {
#if !ASTAR_NO_GRID_GRAPH
                            var gnode = nodes[v] as GridNode;

                            if (gnode != null)
                            {
                                GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex);

                                float v1 = (float)rnd.NextDouble();
                                float v2 = (float)rnd.NextDouble();
                                p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize;
                            }
                            else
#endif
                            {
                                //Point nodes have no area, so we break directly instead
                                pts.Add((Vector3)nodes[v].position);
                                break;
                            }
                        }

                        // Test if it is some distance away from the other points
                        if (clearanceRadius > 0)
                        {
                            for (int j = 0; j < pts.Count; j++)
                            {
                                if ((pts[j] - p).sqrMagnitude < clearanceRadius)
                                {
                                    worked = false;
                                    break;
                                }
                            }
                        }

                        if (worked)
                        {
                            pts.Add(p);
                            break;
                        }
                        testCount++;
                    }
                }

                ListPool <float> .Release(accs);
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    pts.Add((Vector3)nodes[rnd.Next(nodes.Count)].position);
                }
            }

            return(pts);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
 public static long TriangleArea(Int3 a, Int3 b, Int3 c)
 {
     return(Polygon.TriangleArea2(a, b, c));
 }
Ejemplo n.º 6
0
 public static float TriangleArea(Vector3 a, Vector3 b, Vector3 c)
 {
     return(Polygon.TriangleArea2(a, b, c));
 }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
0
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0f)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new ArgumentException("no nodes passed");
            }
            System.Random  random = new System.Random();
            List <Vector3> list   = ListPool <Vector3> .Claim(count);

            clearanceRadius *= clearanceRadius;
            if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode)
            {
                List <float> list2 = ListPool <float> .Claim(nodes.Count);

                float num = 0f;
                for (int i = 0; i < nodes.Count; i++)
                {
                    TriangleMeshNode triangleMeshNode = nodes[i] as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        float num2 = (float)Math.Abs(Polygon.TriangleArea2(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2)));
                        num += num2;
                        list2.Add(num);
                    }
                    else
                    {
                        GridNode gridNode = nodes[i] as GridNode;
                        if (gridNode != null)
                        {
                            GridGraph gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);
                            float     num3      = gridGraph.nodeSize * gridGraph.nodeSize;
                            num += num3;
                            list2.Add(num);
                        }
                        else
                        {
                            list2.Add(num);
                        }
                    }
                }
                for (int j = 0; j < count; j++)
                {
                    int  num4 = 0;
                    int  num5 = 10;
                    bool flag = false;
                    while (!flag)
                    {
                        flag = true;
                        if (num4 >= num5)
                        {
                            clearanceRadius *= 0.8f;
                            num5            += 10;
                            if (num5 > 100)
                            {
                                clearanceRadius = 0f;
                            }
                        }
                        float item = (float)random.NextDouble() * num;
                        int   num6 = list2.BinarySearch(item);
                        if (num6 < 0)
                        {
                            num6 = ~num6;
                        }
                        if (num6 >= nodes.Count)
                        {
                            flag = false;
                        }
                        else
                        {
                            TriangleMeshNode triangleMeshNode2 = nodes[num6] as TriangleMeshNode;
                            Vector3          vector;
                            if (triangleMeshNode2 != null)
                            {
                                float num7;
                                float num8;
                                do
                                {
                                    num7 = (float)random.NextDouble();
                                    num8 = (float)random.NextDouble();
                                }while (num7 + num8 > 1f);
                                vector = (Vector3)(triangleMeshNode2.GetVertex(1) - triangleMeshNode2.GetVertex(0)) * num7 + (Vector3)(triangleMeshNode2.GetVertex(2) - triangleMeshNode2.GetVertex(0)) * num8 + (Vector3)triangleMeshNode2.GetVertex(0);
                            }
                            else
                            {
                                GridNode gridNode2 = nodes[num6] as GridNode;
                                if (gridNode2 == null)
                                {
                                    list.Add((Vector3)nodes[num6].position);
                                    break;
                                }
                                GridGraph gridGraph2 = GridNode.GetGridGraph(gridNode2.GraphIndex);
                                float     num9       = (float)random.NextDouble();
                                float     num10      = (float)random.NextDouble();
                                vector = (Vector3)gridNode2.position + new Vector3(num9 - 0.5f, 0f, num10 - 0.5f) * gridGraph2.nodeSize;
                            }
                            if (clearanceRadius > 0f)
                            {
                                for (int k = 0; k < list.Count; k++)
                                {
                                    if ((list[k] - vector).sqrMagnitude < clearanceRadius)
                                    {
                                        flag = false;
                                        break;
                                    }
                                }
                            }
                            if (flag)
                            {
                                list.Add(vector);
                                break;
                            }
                            num4++;
                        }
                    }
                }
                ListPool <float> .Release(list2);
            }
            else
            {
                for (int l = 0; l < count; l++)
                {
                    list.Add((Vector3)nodes[random.Next(nodes.Count)].position);
                }
            }
            return(list);
        }