Exemple #1
0
        void CalculateMeshContour()
        {
            if (mesh == null)
            {
                return;
            }

            edges.Clear();
            pointers.Clear();

            Vector3[] verts = mesh.vertices;
            int[]     tris  = mesh.triangles;
            for (int i = 0; i < tris.Length; i += 3)
            {
                // Make sure it is clockwise
                if (Polygon.IsClockwise(verts[tris[i + 0]], verts[tris[i + 1]], verts[tris[i + 2]]))
                {
                    int tmp = tris[i + 0];
                    tris[i + 0] = tris[i + 2];
                    tris[i + 2] = tmp;
                }

                edges[new Int2(tris[i + 0], tris[i + 1])] = i;
                edges[new Int2(tris[i + 1], tris[i + 2])] = i;
                edges[new Int2(tris[i + 2], tris[i + 0])] = i;
            }

            // Construct a list of pointers along all edges
            for (int i = 0; i < tris.Length; i += 3)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (!edges.ContainsKey(new Int2(tris[i + ((j + 1) % 3)], tris[i + ((j + 0) % 3)])))
                    {
                        pointers[tris[i + ((j + 0) % 3)]] = tris[i + ((j + 1) % 3)];
                    }
                }
            }

            var contourBuffer = new List <Vector3[]>();

            List <Vector3> buffer = Pathfinding.Util.ListPool <Vector3> .Claim();

            // Follow edge pointers to generate the contours
            for (int i = 0; i < verts.Length; i++)
            {
                if (pointers.ContainsKey(i))
                {
                    buffer.Clear();

                    int s = i;
                    do
                    {
                        int tmp = pointers[s];

                        //This path has been taken before
                        if (tmp == -1)
                        {
                            break;
                        }

                        pointers[s] = -1;
                        buffer.Add(verts[s]);
                        s = tmp;

                        if (s == -1)
                        {
                            Debug.LogError("Invalid Mesh '" + mesh.name + " in " + gameObject.name);
                            break;
                        }
                    } while (s != i);

                    if (buffer.Count > 0)
                    {
                        contourBuffer.Add(buffer.ToArray());
                    }
                }
            }

            // Return lists to the pool
            Pathfinding.Util.ListPool <Vector3> .Release(buffer);

            contours = contourBuffer.ToArray();
        }
Exemple #2
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);
     }
 }
Exemple #3
0
 // Token: 0x06002248 RID: 8776 RVA: 0x0018DCF8 File Offset: 0x0018BEF8
 public void RecalcConvex()
 {
     this.convexPoints = (this.convex ? Polygon.ConvexHullXZ(this.points) : null);
 }
        public List <Vector3> SmoothSimple(List <Vector3> path)
        {
            if (path.Count < 2)
            {
                return(path);
            }

            List <Vector3> subdivided;

            if (uniformLength)
            {
                // Clamp to a small value to avoid the path being divided into a huge number of segments
                maxSegmentLength = Mathf.Max(maxSegmentLength, 0.005f);

                float pathLength = 0;
                for (int i = 0; i < path.Count - 1; i++)
                {
                    pathLength += Vector3.Distance(path[i], path[i + 1]);
                }

                int estimatedNumberOfSegments = Mathf.FloorToInt(pathLength / maxSegmentLength);
                // Get a list with an initial capacity high enough so that we can add all points
                subdivided = ListPool <Vector3> .Claim(estimatedNumberOfSegments + 2);

                float distanceAlong = 0;

                // Sample points every [maxSegmentLength] world units along the path
                for (int i = 0; i < path.Count - 1; i++)
                {
                    var start = path[i];
                    var end   = path[i + 1];

                    float length = Vector3.Distance(start, end);

                    while (distanceAlong < length)
                    {
                        subdivided.Add(Vector3.Lerp(start, end, distanceAlong / length));
                        distanceAlong += maxSegmentLength;
                    }

                    distanceAlong -= length;
                }

                // Make sure we get the exact position of the last point
                subdivided.Add(path[path.Count - 1]);
            }
            else
            {
                subdivisions = Mathf.Max(subdivisions, 0);

                if (subdivisions > 10)
                {
                    Debug.LogWarning("Very large number of subdivisions. Cowardly refusing to subdivide every segment into more than " + (1 << subdivisions) + " subsegments");
                    subdivisions = 10;
                }

                int steps = 1 << subdivisions;
                subdivided = ListPool <Vector3> .Claim((path.Count - 1) *steps + 1);

                Polygon.Subdivide(path, subdivided, steps);
            }

            if (strength > 0)
            {
                for (int it = 0; it < iterations; it++)
                {
                    Vector3 prev = subdivided[0];

                    for (int i = 1; i < subdivided.Count - 1; i++)
                    {
                        Vector3 tmp = subdivided[i];

                        // prev is at this point set to the value that subdivided[i-1] had before this loop started
                        // Move the point closer to the average of the adjacent points
                        subdivided[i] = Vector3.Lerp(tmp, (prev + subdivided[i + 1]) / 2F, strength);

                        prev = tmp;
                    }
                }
            }

            return(subdivided);
        }
 /** Recalculate convex points.
  * Will not do anything if not #convex is enabled
  */
 public void RecalcConvex()
 {
     convexPoints = convex ? Polygon.ConvexHull(points) : null;
 }
Exemple #6
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);
        }
Exemple #7
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            //System.DateTime startTime = System.DateTime.UtcNow;

            Bounds bounds = o.bounds;

            Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);

            var r2 = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.FloorToInt(bounds.max.x * Int3.Precision),
                Mathf.FloorToInt(bounds.max.z * Int3.Precision)
                );

            var a = new Int3(r2.xmin, 0, r2.ymin);
            var b = new Int3(r2.xmin, 0, r2.ymax);
            var c = new Int3(r2.xmax, 0, r2.ymin);
            var d = new Int3(r2.xmax, 0, r2.ymax);

            graph.GetNodes(_node => {
                var node = _node as TriangleMeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                for (int v = 0; v < 3; v++)
                {
                    Int3 p   = node.GetVertex(v);
                    var vert = (Vector3)p;

                    if (r2.Contains(p.x, p.z))
                    {
                        inside = true;
                        break;
                    }

                    if (vert.x < r.xMin)
                    {
                        allLeft++;
                    }
                    if (vert.x > r.xMax)
                    {
                        allRight++;
                    }
                    if (vert.z < r.yMin)
                    {
                        allTop++;
                    }
                    if (vert.z > r.yMax)
                    {
                        allBottom++;
                    }
                }
                if (!inside)
                {
                    if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
                    {
                        return(true);
                    }
                }

                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Int3 vert1 = node.GetVertex(v);
                    Int3 vert2 = node.GetVertex(v2);

                    if (Polygon.Intersects(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }

                if (node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return(true);
                }

                o.WillUpdateNode(node);
                o.Apply(node);
                return(true);
            });
        }
Exemple #8
0
 public static bool ContainsPoint(TriangleMeshNode node, Vector3 pos, VInt3[] vertices)
 {
     if (!Polygon.IsClockwiseMargin((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], (Vector3)vertices[node.v2]))
     {
         Debug.LogError("Noes!");
     }
     return((Polygon.IsClockwiseMargin((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], pos) && Polygon.IsClockwiseMargin((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], pos)) && Polygon.IsClockwiseMargin((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], pos));
 }
        public Vector3 ClampMovement(Vector3 direction)
        {
            Vector3 vector  = direction * this.delta;
            Vector3 vector2 = base.transform.position + direction;
            Vector3 vector3 = vector2;
            float   num     = 0f;
            int     num2    = 0;

            this.vos.Clear();
            float magnitude = this.velocity.magnitude;

            foreach (LocalAvoidance localAvoidance in this.agents)
            {
                if (!(localAvoidance == this) && !(localAvoidance == null))
                {
                    Vector3 vector4    = localAvoidance.transform.position - base.transform.position;
                    float   magnitude2 = vector4.magnitude;
                    float   num3       = this.radius + localAvoidance.radius;
                    if (magnitude2 <= vector.magnitude * this.delta + num3 + magnitude + localAvoidance.GetVelocity().magnitude)
                    {
                        if (num2 <= 50)
                        {
                            num2++;
                            LocalAvoidance.VO vo = new LocalAvoidance.VO();
                            vo.origin    = base.transform.position + Vector3.Lerp(this.velocity * this.delta, localAvoidance.GetVelocity() * this.delta, this.responability);
                            vo.direction = vector4.normalized;
                            if (num3 > vector4.magnitude)
                            {
                                vo.angle = 1.57079637f;
                            }
                            else
                            {
                                vo.angle = (float)Math.Asin((double)(num3 / magnitude2));
                            }
                            vo.limit = magnitude2 - num3;
                            if (vo.limit < 0f)
                            {
                                vo.origin += vo.direction * vo.limit;
                                vo.limit   = 0f;
                            }
                            float num4 = Mathf.Atan2(vo.direction.z, vo.direction.x);
                            vo.pRight = new Vector3(Mathf.Cos(num4 + vo.angle), 0f, Mathf.Sin(num4 + vo.angle));
                            vo.pLeft  = new Vector3(Mathf.Cos(num4 - vo.angle), 0f, Mathf.Sin(num4 - vo.angle));
                            vo.nLeft  = new Vector3(Mathf.Cos(num4 + vo.angle - 1.57079637f), 0f, Mathf.Sin(num4 + vo.angle - 1.57079637f));
                            vo.nRight = new Vector3(Mathf.Cos(num4 - vo.angle + 1.57079637f), 0f, Mathf.Sin(num4 - vo.angle + 1.57079637f));
                            this.vos.Add(vo);
                        }
                    }
                }
            }
            if (this.resType == LocalAvoidance.ResolutionType.Geometric)
            {
                for (int j = 0; j < this.vos.Count; j++)
                {
                    if (this.vos[j].Contains(vector3))
                    {
                        num = float.PositiveInfinity;
                        if (this.drawGizmos)
                        {
                            Debug.DrawRay(vector3, Vector3.down, Color.red);
                        }
                        vector3 = base.transform.position;
                        break;
                    }
                }
                if (this.drawGizmos)
                {
                    for (int k = 0; k < this.vos.Count; k++)
                    {
                        this.vos[k].Draw(Color.black);
                    }
                }
                if (num == 0f)
                {
                    return(vector);
                }
                List <LocalAvoidance.VOLine> list = new List <LocalAvoidance.VOLine>();
                for (int l = 0; l < this.vos.Count; l++)
                {
                    LocalAvoidance.VO vo2     = this.vos[l];
                    float             num5    = (float)Math.Atan2((double)vo2.direction.z, (double)vo2.direction.x);
                    Vector3           vector5 = vo2.origin + new Vector3((float)Math.Cos((double)(num5 + vo2.angle)), 0f, (float)Math.Sin((double)(num5 + vo2.angle))) * vo2.limit;
                    Vector3           vector6 = vo2.origin + new Vector3((float)Math.Cos((double)(num5 - vo2.angle)), 0f, (float)Math.Sin((double)(num5 - vo2.angle))) * vo2.limit;
                    Vector3           end     = vector5 + new Vector3((float)Math.Cos((double)(num5 + vo2.angle)), 0f, (float)Math.Sin((double)(num5 + vo2.angle))) * 100f;
                    Vector3           end2    = vector6 + new Vector3((float)Math.Cos((double)(num5 - vo2.angle)), 0f, (float)Math.Sin((double)(num5 - vo2.angle))) * 100f;
                    int num6 = (!Polygon.Left(vo2.origin, vo2.origin + vo2.direction, base.transform.position + this.velocity)) ? 2 : 1;
                    list.Add(new LocalAvoidance.VOLine(vo2, vector5, end, true, 1, num6 == 1));
                    list.Add(new LocalAvoidance.VOLine(vo2, vector6, end2, true, 2, num6 == 2));
                    list.Add(new LocalAvoidance.VOLine(vo2, vector5, vector6, false, 3, false));
                    bool flag  = false;
                    bool flag2 = false;
                    if (!flag)
                    {
                        for (int m = 0; m < this.vos.Count; m++)
                        {
                            if (m != l && this.vos[m].Contains(vector5))
                            {
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (!flag2)
                    {
                        for (int n = 0; n < this.vos.Count; n++)
                        {
                            if (n != l && this.vos[n].Contains(vector6))
                            {
                                flag2 = true;
                                break;
                            }
                        }
                    }
                    vo2.AddInt(0f, flag, 1);
                    vo2.AddInt(0f, flag2, 2);
                    vo2.AddInt(0f, flag, 3);
                    vo2.AddInt(1f, flag2, 3);
                }
                for (int num7 = 0; num7 < list.Count; num7++)
                {
                    for (int num8 = num7 + 1; num8 < list.Count; num8++)
                    {
                        LocalAvoidance.VOLine voline  = list[num7];
                        LocalAvoidance.VOLine voline2 = list[num8];
                        if (voline.vo != voline2.vo)
                        {
                            float num9;
                            float num10;
                            if (Polygon.IntersectionFactor(voline.start, voline.end, voline2.start, voline2.end, out num9, out num10))
                            {
                                if (num9 >= 0f && num10 >= 0f && (voline.inf || num9 <= 1f) && (voline2.inf || num10 <= 1f))
                                {
                                    Vector3 p     = voline.start + (voline.end - voline.start) * num9;
                                    bool    flag3 = voline.wrongSide || voline2.wrongSide;
                                    if (!flag3)
                                    {
                                        for (int num11 = 0; num11 < this.vos.Count; num11++)
                                        {
                                            if (this.vos[num11] != voline.vo && this.vos[num11] != voline2.vo && this.vos[num11].Contains(p))
                                            {
                                                flag3 = true;
                                                break;
                                            }
                                        }
                                    }
                                    voline.vo.AddInt(num9, flag3, voline.id);
                                    voline2.vo.AddInt(num10, flag3, voline2.id);
                                    if (this.drawGizmos)
                                    {
                                        Debug.DrawRay(voline.start + (voline.end - voline.start) * num9, Vector3.up, (!flag3) ? Color.green : Color.magenta);
                                    }
                                }
                            }
                        }
                    }
                }
                for (int num12 = 0; num12 < this.vos.Count; num12++)
                {
                    Vector3 vector7;
                    if (this.vos[num12].FinalInts(vector2, base.transform.position + this.velocity, this.drawGizmos, out vector7))
                    {
                        float sqrMagnitude = (vector7 - vector2).sqrMagnitude;
                        if (sqrMagnitude < num)
                        {
                            vector3 = vector7;
                            num     = sqrMagnitude;
                            if (this.drawGizmos)
                            {
                                Debug.DrawLine(vector2 + Vector3.up, vector3 + Vector3.up, Color.red);
                            }
                        }
                    }
                }
                if (this.drawGizmos)
                {
                    Debug.DrawLine(vector2 + Vector3.up, vector3 + Vector3.up, Color.red);
                }
                return(Vector3.ClampMagnitude(vector3 - base.transform.position, vector.magnitude * this.maxSpeedScale));
            }
            else
            {
                if (this.resType == LocalAvoidance.ResolutionType.Sampled)
                {
                    Vector3 vector8    = vector;
                    Vector3 normalized = vector8.normalized;
                    Vector3 vector9    = Vector3.Cross(normalized, Vector3.up);
                    int     num13      = 10;
                    int     num14      = 0;
                    while (num14 < 10)
                    {
                        float num15 = (float)(3.1415926535897931 * (double)this.circlePoint / (double)num13);
                        float num16 = (float)(3.1415926535897931 - (double)this.circlePoint * 3.1415926535897931) * 0.5f;
                        for (int num17 = 0; num17 < num13; num17++)
                        {
                            float   num18    = num15 * (float)num17;
                            Vector3 vector10 = base.transform.position + vector - (vector8 * (float)Math.Sin((double)(num18 + num16)) * (float)num14 * this.circleScale + vector9 * (float)Math.Cos((double)(num18 + num16)) * (float)num14 * this.circleScale);
                            if (this.CheckSample(vector10, this.vos))
                            {
                                return(vector10 - base.transform.position);
                            }
                        }
                        num14++;
                        num13 += 2;
                    }
                    for (int num19 = 0; num19 < this.samples.Length; num19++)
                    {
                        Vector3 vector11 = base.transform.position + this.samples[num19].x * vector9 + this.samples[num19].z * normalized + this.samples[num19].y * vector8;
                        if (this.CheckSample(vector11, this.vos))
                        {
                            return(vector11 - base.transform.position);
                        }
                    }
                    return(Vector3.zero);
                }
                return(Vector3.zero);
            }
        }
Exemple #10
0
 /** Returns if the triangle \a ABC contains the point \a p in XZ space */
 public static bool ContainsPoint(Vector3 a, Vector3 b, Vector3 c, Vector3 p)
 {
     return(Polygon.IsClockwiseMargin(a, b, p) && Polygon.IsClockwiseMargin(b, c, p) && Polygon.IsClockwiseMargin(c, a, p));
 }
 void CalculateConvexHull()
 {
     _convexPoints = points != null?Polygon.ConvexHullXZ(points) : null;
 }
Exemple #12
0
        public static 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);
        }
Exemple #13
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);
        }
Exemple #14
0
 public static Vector3 ClosestPointOnNode(TriangleMeshNode node, VInt3[] vertices, Vector3 pos)
 {
     return(Polygon.ClosestPointOnTriangle((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], (Vector3)vertices[node.v2], pos));
 }
Exemple #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];

            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();

            //Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
        }
Exemple #16
0
 public bool ContainsPoint(TriangleMeshNode node, Vector3 pos)
 {
     return((Polygon.IsClockwise((Vector3)this.vertices[node.v0], (Vector3)this.vertices[node.v1], pos) && Polygon.IsClockwise((Vector3)this.vertices[node.v1], (Vector3)this.vertices[node.v2], pos)) && Polygon.IsClockwise((Vector3)this.vertices[node.v2], (Vector3)this.vertices[node.v0], pos));
 }
Exemple #17
0
        public bool FindNextCorners(Vector3 origin, int startIndex, List <Vector3> funnelPath, int numCorners, out bool lastCorner)
        {
            lastCorner = false;

            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");
            }

            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);
        }
Exemple #18
0
 public void RecalcConvex()
 {
     this.convexPoints = ((!this.convex) ? null : Polygon.ConvexHullXZ(this.points));
 }
Exemple #19
0
        private void CalculateMeshContour()
        {
            if (this.mesh == null)
            {
                return;
            }
            NavmeshCut.edges.Clear();
            NavmeshCut.pointers.Clear();
            Vector3[] vertices  = this.mesh.vertices;
            int[]     triangles = this.mesh.triangles;
            for (int i = 0; i < triangles.Length; i += 3)
            {
                if (Polygon.IsClockwise(vertices[triangles[i]], vertices[triangles[i + 1]], vertices[triangles[i + 2]]))
                {
                    int num = triangles[i];
                    triangles[i]     = triangles[i + 2];
                    triangles[i + 2] = num;
                }
                NavmeshCut.edges[new Int2(triangles[i], triangles[i + 1])]     = i;
                NavmeshCut.edges[new Int2(triangles[i + 1], triangles[i + 2])] = i;
                NavmeshCut.edges[new Int2(triangles[i + 2], triangles[i])]     = i;
            }
            for (int j = 0; j < triangles.Length; j += 3)
            {
                for (int k = 0; k < 3; k++)
                {
                    if (!NavmeshCut.edges.ContainsKey(new Int2(triangles[j + (k + 1) % 3], triangles[j + k % 3])))
                    {
                        NavmeshCut.pointers[triangles[j + k % 3]] = triangles[j + (k + 1) % 3];
                    }
                }
            }
            List <Vector3[]> list  = new List <Vector3[]>();
            List <Vector3>   list2 = ListPool <Vector3> .Claim();

            for (int l = 0; l < vertices.Length; l++)
            {
                if (NavmeshCut.pointers.ContainsKey(l))
                {
                    list2.Clear();
                    int num2 = l;
                    do
                    {
                        int num3 = NavmeshCut.pointers[num2];
                        if (num3 == -1)
                        {
                            break;
                        }
                        NavmeshCut.pointers[num2] = -1;
                        list2.Add(vertices[num2]);
                        num2 = num3;
                        if (num2 == -1)
                        {
                            goto Block_9;
                        }
                    }while (num2 != l);
IL_20C:
                    if (list2.Count > 0)
                    {
                        list.Add(list2.ToArray());
                        goto IL_227;
                    }
                    goto IL_227;
Block_9:
                    Debug.LogError("Invalid Mesh '" + this.mesh.name + " in " + base.gameObject.name);
                    goto IL_20C;
                }
                IL_227 :;
            }
            ListPool <Vector3> .Release(list2);

            this.contours = list.ToArray();
        }
        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);
        }
Exemple #21
0
        /** Calculate a funnel path from the \a left and \a right portal lists.
         * The result will be appended to \a funnelPath
         */
        public 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);
        }
Exemple #22
0
        public override Vector3 ClosestPointOnNode(Vector3 p)
        {
            INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(base.GraphIndex);

            return(Polygon.ClosestPointOnTriangle((Vector3)navmeshHolder.GetVertex(this.v0), (Vector3)navmeshHolder.GetVertex(this.v1), (Vector3)navmeshHolder.GetVertex(this.v2), p));
        }
Exemple #23
0
        // Token: 0x0600266D RID: 9837 RVA: 0x001A7318 File Offset: 0x001A5518
        public List <Vector3> SmoothSimple(List <Vector3> path)
        {
            if (path.Count < 2)
            {
                return(path);
            }
            List <Vector3> list;

            if (this.uniformLength)
            {
                this.maxSegmentLength = Mathf.Max(this.maxSegmentLength, 0.005f);
                float num = 0f;
                for (int i = 0; i < path.Count - 1; i++)
                {
                    num += Vector3.Distance(path[i], path[i + 1]);
                }
                list = ListPool <Vector3> .Claim(Mathf.FloorToInt(num / this.maxSegmentLength) + 2);

                float num2 = 0f;
                for (int j = 0; j < path.Count - 1; j++)
                {
                    Vector3 a    = path[j];
                    Vector3 b    = path[j + 1];
                    float   num3 = Vector3.Distance(a, b);
                    while (num2 < num3)
                    {
                        list.Add(Vector3.Lerp(a, b, num2 / num3));
                        num2 += this.maxSegmentLength;
                    }
                    num2 -= num3;
                }
                list.Add(path[path.Count - 1]);
            }
            else
            {
                this.subdivisions = Mathf.Max(this.subdivisions, 0);
                if (this.subdivisions > 10)
                {
                    Debug.LogWarning("Very large number of subdivisions. Cowardly refusing to subdivide every segment into more than " + (1 << this.subdivisions) + " subsegments");
                    this.subdivisions = 10;
                }
                int num4 = 1 << this.subdivisions;
                list = ListPool <Vector3> .Claim((path.Count - 1) *num4 + 1);

                Polygon.Subdivide(path, list, num4);
            }
            if (this.strength > 0f)
            {
                for (int k = 0; k < this.iterations; k++)
                {
                    Vector3 a2 = list[0];
                    for (int l = 1; l < list.Count - 1; l++)
                    {
                        Vector3 vector = list[l];
                        list[l] = Vector3.Lerp(vector, (a2 + list[l + 1]) / 2f, this.strength);
                        a2      = vector;
                    }
                }
            }
            return(list);
        }