Пример #1
0
        public void Apply(bool forceNewCheck)
        {
            //TODO
            //This function assumes that connections from the n1,n2 nodes never need to be removed in the future (e.g because the nodes move or something)
            NNConstraint nn = NNConstraint.None;

            nn.distanceXZ = true;
            int graph = (int)startNode.GraphIndex;

            //Search all graphs but the one which start and end nodes are on
            nn.graphMask = ~(1 << graph);

            bool same = true;

            {
                //Good Game
                //var info = AstarPath.active.GetNearest(StartTransform.position, nn);
                var info = AstarPath.active.GetNearest((VInt3)StartTransform.position, nn);
                same          &= info.node == connectedNode1 && info.node != null;
                connectedNode1 = info.node as MeshNode;
                clamped1       = info.position;
                if (connectedNode1 != null)
                {
                    Debug.DrawRay((Vector3)connectedNode1.position, Vector3.up * 5, Color.red);
                }
            }

            {
                //Good Game
                //var info = AstarPath.active.GetNearest(EndTransform.position, nn);
                var info = AstarPath.active.GetNearest((VInt3)EndTransform.position, nn);
                same          &= info.node == connectedNode2 && info.node != null;
                connectedNode2 = info.node as MeshNode;
                clamped2       = info.position;
                if (connectedNode2 != null)
                {
                    Debug.DrawRay((Vector3)connectedNode2.position, Vector3.up * 5, Color.cyan);
                }
            }

            if (connectedNode2 == null || connectedNode1 == null)
            {
                return;
            }

            startNode.SetPosition((VInt3)StartTransform.position);
            endNode.SetPosition((VInt3)EndTransform.position);

            if (same && !forceNewCheck)
            {
                return;
            }

            RemoveConnections(startNode);
            RemoveConnections(endNode);

            uint cost = (uint)Mathf.RoundToInt(((VInt3)(StartTransform.position - EndTransform.position)).costMagnitude * costFactor);

            startNode.AddConnection(endNode, cost);
            endNode.AddConnection(startNode, cost);

            VInt3 dir = connectedNode2.position - connectedNode1.position;

            for (int a = 0; a < connectedNode1.GetVertexCount(); a++)
            {
                VInt3 va1 = connectedNode1.GetVertex(a);
                VInt3 va2 = connectedNode1.GetVertex((a + 1) % connectedNode1.GetVertexCount());

                if (VInt3.DotLong((va2 - va1).Normal2D(), dir) > 0)
                {
                    continue;
                }

                for (int b = 0; b < connectedNode2.GetVertexCount(); b++)
                {
                    VInt3 vb1 = connectedNode2.GetVertex(b);
                    VInt3 vb2 = connectedNode2.GetVertex((b + 1) % connectedNode2.GetVertexCount());

                    if (VInt3.DotLong((vb2 - vb1).Normal2D(), dir) < 0)
                    {
                        continue;
                    }

                    if (VInt3.Angle((vb2 - vb1), (va2 - va1)) > (170.0 / 360.0f) * Mathf.PI * 2)
                    {
                        float t1 = 0;
                        float t2 = 1;

                        t2 = System.Math.Min(t2, VectorMath.ClosestPointOnLineFactor(va1, va2, vb1));
                        t1 = System.Math.Max(t1, VectorMath.ClosestPointOnLineFactor(va1, va2, vb2));

                        if (t2 < t1)
                        {
                            Debug.LogError("Something went wrong! " + t1 + " " + t2 + " " + va1 + " " + va2 + " " + vb1 + " " + vb2 + "\nTODO, how can this happen?");
                        }
                        else
                        {
                            //Good Game

                            /*Vector3 pa = (Vector3)(va2-va1)*t1 + (Vector3)va1;
                            *                           Vector3 pb = (Vector3)(va2-va1)*t2 + (Vector3)va1;*/
                            VInt3 pa = (va2 - va1) * t1 + va1;
                            VInt3 pb = (va2 - va1) * t2 + va1;

                            startNode.portalA = pa;
                            startNode.portalB = pb;

                            endNode.portalA = pb;
                            endNode.portalB = pa;

                            //Add connections between nodes, or replace old connections if existing
                            //Good Game

                            /*connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt(((VInt3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
                             *                          connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt(((VInt3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
                             *
                             *                          startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt(((VInt3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
                             *                          endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt(((VInt3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));*/
                            connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt(((clamped1 - (VInt3)StartTransform.position)).costMagnitude * costFactor));
                            connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt(((clamped2 - (VInt3)EndTransform.position)).costMagnitude * costFactor));

                            startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt(((clamped1 - (VInt3)StartTransform.position)).costMagnitude * costFactor));
                            endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt(((clamped2 - (VInt3)EndTransform.position)).costMagnitude * costFactor));

                            return;
                        }
                    }
                }
            }
        }
Пример #2
0
        private void DelaunayRefinement(VInt3[] verts, int[] tris, ref int vCount, ref int tCount, bool delaunay, bool colinear, VInt3 worldOffset)
        {
            if (tCount % 3 != 0)
            {
                throw new Exception("Triangle array length must be a multiple of 3");
            }
            Dictionary <VInt2, int> dictionary = this.cached_Int2_int_dict;

            dictionary.Clear();
            for (int i = 0; i < tCount; i += 3)
            {
                if (!Polygon.IsClockwise(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]]))
                {
                    int num = tris[i];
                    tris[i]     = tris[i + 2];
                    tris[i + 2] = num;
                }
                dictionary.set_Item(new VInt2(tris[i], tris[i + 1]), i + 2);
                dictionary.set_Item(new VInt2(tris[i + 1], tris[i + 2]), i);
                dictionary.set_Item(new VInt2(tris[i + 2], tris[i]), i + 1);
            }
            int num2 = 9;

            for (int j = 0; j < tCount; j += 3)
            {
                for (int k = 0; k < 3; k++)
                {
                    int num3;
                    if (dictionary.TryGetValue(new VInt2(tris[j + (k + 1) % 3], tris[j + k % 3]), ref num3))
                    {
                        VInt3 vInt  = verts[tris[j + (k + 2) % 3]];
                        VInt3 vInt2 = verts[tris[j + (k + 1) % 3]];
                        VInt3 vInt3 = verts[tris[j + (k + 3) % 3]];
                        VInt3 vInt4 = verts[tris[num3]];
                        vInt.y  = 0;
                        vInt2.y = 0;
                        vInt3.y = 0;
                        vInt4.y = 0;
                        bool flag = false;
                        if (!Polygon.Left(vInt, vInt3, vInt4) || Polygon.LeftNotColinear(vInt, vInt2, vInt4))
                        {
                            if (!colinear)
                            {
                                goto IL_439;
                            }
                            flag = true;
                        }
                        if (colinear && AstarMath.DistancePointSegment(vInt, vInt4, vInt2) < (float)num2 && !dictionary.ContainsKey(new VInt2(tris[j + (k + 2) % 3], tris[j + (k + 1) % 3])) && !dictionary.ContainsKey(new VInt2(tris[j + (k + 1) % 3], tris[num3])))
                        {
                            tCount -= 3;
                            int num4 = num3 / 3 * 3;
                            tris[j + (k + 1) % 3] = tris[num3];
                            if (num4 != tCount)
                            {
                                tris[num4]     = tris[tCount];
                                tris[num4 + 1] = tris[tCount + 1];
                                tris[num4 + 2] = tris[tCount + 2];
                                dictionary.set_Item(new VInt2(tris[num4], tris[num4 + 1]), num4 + 2);
                                dictionary.set_Item(new VInt2(tris[num4 + 1], tris[num4 + 2]), num4);
                                dictionary.set_Item(new VInt2(tris[num4 + 2], tris[num4]), num4 + 1);
                                tris[tCount]     = 0;
                                tris[tCount + 1] = 0;
                                tris[tCount + 2] = 0;
                            }
                            else
                            {
                                tCount += 3;
                            }
                            dictionary.set_Item(new VInt2(tris[j], tris[j + 1]), j + 2);
                            dictionary.set_Item(new VInt2(tris[j + 1], tris[j + 2]), j);
                            dictionary.set_Item(new VInt2(tris[j + 2], tris[j]), j + 1);
                        }
                        else if (delaunay && !flag)
                        {
                            float num5 = VInt3.Angle(vInt2 - vInt, vInt3 - vInt);
                            float num6 = VInt3.Angle(vInt2 - vInt4, vInt3 - vInt4);
                            if (num6 > 6.28318548f - 2f * num5)
                            {
                                tris[j + (k + 1) % 3] = tris[num3];
                                int num7 = num3 / 3 * 3;
                                int num8 = num3 - num7;
                                tris[num7 + (num8 - 1 + 3) % 3] = tris[j + (k + 2) % 3];
                                dictionary.set_Item(new VInt2(tris[j], tris[j + 1]), j + 2);
                                dictionary.set_Item(new VInt2(tris[j + 1], tris[j + 2]), j);
                                dictionary.set_Item(new VInt2(tris[j + 2], tris[j]), j + 1);
                                dictionary.set_Item(new VInt2(tris[num7], tris[num7 + 1]), num7 + 2);
                                dictionary.set_Item(new VInt2(tris[num7 + 1], tris[num7 + 2]), num7);
                                dictionary.set_Item(new VInt2(tris[num7 + 2], tris[num7]), num7 + 1);
                            }
                        }
                    }
                    IL_439 :;
                }
            }
        }