public int SharedEdge(NavmeshTriangle other)
        {
            int a, b;

            GetPortal(other, out a, out b);
            return(a);
        }
Exemple #2
0
        void Buildsegments()
        {
            segments.Clear();

            for (int i = 0; i < ObsTriangles.Length; i++)
            {
                NavmeshTriangle node = ObsTriangles [i];
                for (int j = 0; j < node.shared.Count; ++j)
                {
                    if (node.shared[j] == false)
                    {
                        segments.Add(node.GetSegment(j));
                    }
                }

                ShowProgress("构建单边列表", (float)i / (ObsTriangles.Length));
            }

            DefineIDforSegments(segments);
        }
 public bool isSharedEdge(NavmeshTriangle other, out int idx)
 {
     for (int i = 0; i < 3; ++i)
     {
         KInt2 p1 = GetXZVertex(i);
         KInt2 p2 = GetXZVertex((i + 1) % 3);
         for (int k = 0; k < 3; ++k)
         {
             KInt2 p3 = other.GetXZVertex(k);
             KInt2 p4 = other.GetXZVertex((k + 1) % 3);
             if ((p1 == p3 && p2 == p4) || (p1 == p4 && p2 == p3))
             {
                 idx = i;
                 return(true);
             }
         }
     }
     idx = -1;
     return(false);
 }
        public void GetPortal(NavmeshTriangle other, out int aIndex, out int bIndex)
        {
            int first  = -1;
            int second = -1;

            for (int a = 0; a < 3; a++)
            {
                int va = GetVertexIndex(a);
                for (int b = 0; b < 3; b++)
                {
                    if (va == other.GetVertexIndex((b + 1) % 3) && GetVertexIndex((a + 1) % 3) == other.GetVertexIndex(b))
                    {
                        first  = a;
                        second = b;
                        a      = 3;
                        break;
                    }
                }
            }

            aIndex = first;
            bIndex = second;
        }
Exemple #5
0
        bool Mesh2Obstacle()
        {
            if (mesh.vertexCount == 0 || mesh.triangles.Length == 0)
            {
                LogMgr.LogError("Convert Error");
                return(false);
            }
            BeginSample("Mesh2Obstacle");
            //old
            Vector3[] vectorVertices = mesh.vertices;
            int[]     triangles      = mesh.triangles;

            //create new
            KInt3[] vertices = new KInt3[mesh.vertexCount];

            Dictionary <KInt3, int> hashedVerts = new Dictionary <KInt3, int> (mesh.vertexCount);

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

            //从模型坐标系转换到世界坐标系
            for (int i = 0; i < vertices.Length; i++)
            {
                vertices [i] = (KInt3)MeshMatrix.MultiplyPoint3x4(vectorVertices [i]);
                ShowProgress("从模型坐标系转换到世界坐标系", (float)i / vertices.Length);
            }
            //旧顶点在新顶点中的索引
            int newVerIdx = 0;

            for (int i = 0; i < vertices.Length; i++)
            {
                //当hash 顶点集合不包含这个顶点的时候,把这个点加入进去,去除共点
                if (!hashedVerts.ContainsKey(vertices [i]))
                {
                    newVertices [newVerIdx] = i;
                    hashedVerts.Add(vertices [i], newVerIdx);
                    newVerIdx++;
                }
                ShowProgress("构建映射", (float)i / vertices.Length);
            }

            for (int x = 0; x < triangles.Length; x++)
            {
                //把老的顶点索引映射到新的顶点索引上
                KInt3 vertex = vertices [triangles [x]];

                triangles [x] = hashedVerts [vertex];
                ShowProgress("三角映射", (float)x / triangles.Length);
            }

            KInt3[] totalIntVertices = vertices;
            vertices = new KInt3[newVerIdx];
            for (int i = 0; i < newVerIdx; i++)
            {
                vertices [i] = totalIntVertices [newVertices [i]];
                ShowProgress("顶点索引转换", (float)i / newVerIdx);
            }
            //顶点创建结束
#if UNITY_EDITOR
            this.ObsVertices = vertices;
#endif
            if (triangles.Length % 3 != 0)
            {
                LogMgr.LogErrorFormat("triangle lenth error :{0}", triangles.Length);
            }

            //创建三角
            ObsTriangles = new NavmeshTriangle[triangles.Length / 3];

            for (int i = 0; i < ObsTriangles.Length; i++)
            {
                NavmeshTriangle tri = new NavmeshTriangle();
                ObsTriangles [i] = tri;
#if UNITY_EDITOR
                //init
                tri.uid = i;
#endif
                //
                tri.v0 = triangles [i * 3];
                tri.v1 = triangles [i * 3 + 1];
                tri.v2 = triangles [i * 3 + 2];

                if (RVOMath.IsClockwiseXZ(vertices [tri.v0], vertices [tri.v1], vertices [tri.v2]) == false)
                {
                    int tmp = tri.v0;
                    tri.v0 = tri.v2;
                    tri.v2 = tmp;
                }

                //finish position
                tri.v03 = vertices [tri.v0];
                tri.v13 = vertices [tri.v1];
                tri.v23 = vertices [tri.v2];

                tri.v03xz = new KInt2(tri.v03.x, tri.v03.z);
                tri.v13xz = new KInt2(tri.v13.x, tri.v13.z);
                tri.v23xz = new KInt2(tri.v23.x, tri.v23.z);

                tri.averagePos = (tri.v03 + tri.v13 + tri.v23) / 3;

                if (this.ExactMode >= ExactType.TWO)
                {
                    tri.xzPos = new KInt2(tri.averagePos.x, tri.averagePos.z);

                    if (point2triangle.ContainsKey(tri.xzPos))
                    {
                        point2triangle [tri.xzPos].Add(tri);
                    }
                    else
                    {
                        point2triangle [tri.xzPos] = new List <NavmeshTriangle> ();
                        point2triangle [tri.xzPos].Add(tri);
                    }
                }

                ShowProgress("构建三角形", (float)i / ObsTriangles.Length);
            }

            Dictionary <KInt2, NavmeshTriangle> sides = new Dictionary <KInt2, NavmeshTriangle> (triangles.Length * 3);

            //创建三角形的边
            for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
            {
                sides [KInt2.ToInt2(triangles [i + 0], triangles [i + 1])] = ObsTriangles [j];
                sides [KInt2.ToInt2(triangles [i + 1], triangles [i + 2])] = ObsTriangles [j];
                sides [KInt2.ToInt2(triangles [i + 2], triangles [i + 0])] = ObsTriangles [j];
            }

            HashSet <NavmeshTriangle> connections = new HashSet <NavmeshTriangle> ();

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

                NavmeshTriangle node = ObsTriangles [j];

                for (int q = 0; q < 3; q++)
                {
                    NavmeshTriangle other;
                    //如果是mesh中的边,则加入
                    if (sides.TryGetValue(KInt2.ToInt2(triangles [i + ((q + 1) % 3)], triangles [i + q]), out other))
                    {
                        connections.Add(other);
                    }
                }
                //拷贝当前的一份连接点,而不是赋值引用过去
                node.connections = new List <NavmeshTriangle> ();
                node.connections.AddRange(connections);

                node.CreateSharedInfo();
                ShowProgress("构建连接点", (float)i / (triangles.Length / 3));
            }
            ClearProgressBar();
            EndSample();

            return(true);
        }
Exemple #6
0
        void TriangleCheck(List <NavmeshTriangle> testtriangles, Dictionary <KInt2, HashSet <Segment> > IntersectCache, List <Segment> removeList, Segment TestSegment)
        {
            HashSet <Segment> hitCache = null;

            if (IntersectCache.ContainsKey(TestSegment.start))
            {
                hitCache = IntersectCache [TestSegment.start];
            }

            if (IntersectCache.ContainsKey(TestSegment.end))
            {
                HashSet <Segment> cache = IntersectCache [TestSegment.end];
                if (cache != null)
                {
                    if (hitCache == null)
                    {
                        hitCache = cache;
                    }
                    else
                    {
                        var en = cache.GetEnumerator();
                        while (en.MoveNext())
                        {
                            hitCache.Add(en.Current);
                        }
                    }
                }
            }

            for (int PassedTricnt = 0; PassedTricnt < testtriangles.Count; ++PassedTricnt)
            {
                NavmeshTriangle targettriangle = testtriangles [PassedTricnt];

                int insidecnt = 0;
                int hitcnt    = 0;
                int concnt    = 0;

                KInt2 result;

                for (int j = 0; j < 3; ++j)
                {
                    Segment side = targettriangle.GetSegment(j);
                    bool    h1   = hitCache != null && hitCache.Contains(side);
                    bool    h2   = Segment.Intersect(TestSegment.start, TestSegment.end, side.start, side.end, out result);
                    if (h1 || h2)
                    {
                        hitcnt++;
                    }

                    if (side.ContainsSegment(TestSegment))
                    {
                        insidecnt++;
                    }

                    if (TestSegment.isConnect(side))
                    {
                        concnt++;
                    }
                }

                if (insidecnt == 0 && concnt == 0)
                {
                    int b1 = isInside(targettriangle.v03xz, targettriangle.v13xz, targettriangle.v23xz, TestSegment.start, ErrorRadius);
                    int b2 = isInside(targettriangle.v03xz, targettriangle.v13xz, targettriangle.v23xz, TestSegment.end, ErrorRadius);
                    if (b1 == 2 && b2 == 2)
                    {
                        removeList.Add(TestSegment);
                        break;
                    }
                    else if ((b1 == 1 && b2 == 2) || (b1 == 2 && b2 == 1))
                    {
                        removeList.Add(TestSegment);
                        break;
                    }
                    else if ((b1 <= 1 && b2 <= 1) && hitcnt == 2)
                    {
                        removeList.Add(TestSegment);
                        break;
                    }
                    else if ((b1 == 2 || b2 == 2) && hitcnt > 0)
                    {
                        removeList.Add(TestSegment);
                        break;
                    }
                }

                ShowProgress("三角相交检测 移除相交线段", (float)PassedTricnt / testtriangles.Count);
            }
        }
Exemple #7
0
        void Add2Rvo()
        {
            BeginSample("Add2Rvo");
            float firsttime = Time.realtimeSinceStartup;

            if (ExactMode == ExactType.ZERO)
            {
                BeginSample("ZERO COST");
                int[] uses = new int[20];

                for (int i = 0; i < ObsTriangles.Length; i++)
                {
                    NavmeshTriangle node = ObsTriangles [i];

                    uses [0] = uses [1] = uses [2] = 0;

                    if (node != null)
                    {
                        for (int j = 0; j < node.connections.Count; j++)
                        {
                            NavmeshTriangle other = node.connections [j];
                            if (other != null)
                            {
                                int a = node.SharedEdge(other);
                                if (a != -1)
                                {
                                    uses [a] = 1;
                                }
                            }
                        }

                        for (int j = 0; j < 3; j++)
                        {
                            if (uses [j] == 0)
                            {
                                var v1 = node.GetVertex(j);
                                var v2 = node.GetVertex((j + 1) % 3);

                                Simulator.Instance.addObstacle(v1, v2);
                            }
                        }
                    }

                    ShowProgress("插入障碍点", (float)i / (ObsTriangles.Length));
                }
                EndSample();
            }


            if (ExactMode >= ExactType.ONE)
            {
                BeginSample("Buildsegments");
                Buildsegments();
                EndSample();

                BeginSample("RemoveUnused");
                RemoveUnused();
                EndSample();

                BeginSample("PushSegmentstoObstacles");
                PushSegmentstoObstacles();
                EndSample();
            }

            ShowProgress("准备构建ObstacleTree", 0);
            float time = Time.realtimeSinceStartup;

            BeginSample("processObstacles");
            if (processObstacles)
            {
                Simulator.Instance.processObstacles();
            }
            EndSample();
            LogMgr.LogFormat("Add2Rvo cost :{0}  processObstacles cost :{1} ", Time.realtimeSinceStartup - firsttime, Time.realtimeSinceStartup - time);
            ShowProgress("构建ObstacleTree 完成", 1);
            this.ClearProgressBar();
            EndSample();

#if !UNITY_EDITOR
            ObsTriangles   = null;
            segments       = null;
            tree           = null;
            point2triangle = null;
#else
            if (ObstacleDebug >= DebugMode.ShowAll && UnityEditor.EditorUtility.DisplayDialog("tips", "export kdtree asset or not ?", "OK", "NO"))
            {
                string assetpath = UnityEditor.EditorUtility.SaveFilePanelInProject("save", "kdtree", "asset", "please enter a filename");
                if (!string.IsNullOrEmpty(assetpath))
                {
                    KdtreeAsset   node = ScriptableObject.CreateInstance <KdtreeAsset> ();
                    ScriptCommand cmd  = ScriptCommand.Create((int)FrameWorkCmdDefine.GET_KDTREE);
                    cmd.Excute();

                    ScriptCommand obscmd = ScriptCommand.Create((int)FrameWorkCmdDefine.GET_OBSTACLES);
                    obscmd.Excute();

                    KdTree           tree      = cmd.ReturnParams.ReadObject() as KdTree;
                    IList <Obstacle> obstacles = obscmd.ReturnParams.ReadObject() as IList <Obstacle>;
                    node.CreateKdtree(tree, obstacles);

                    cmd.Release(true);
                    obscmd.Release(true);

                    UnityEditor.AssetDatabase.CreateAsset(node, assetpath);
                }
            }
#endif
        }
Exemple #8
0
        void OnDrawGizmos()
        {
            if (ObsTriangles == null || !DrawGizmos)
            {
                return;
            }

            bool show = !Drawsegments && !DrawRmovelist && !DrawNearstTriangles && DrawGizmos;

            if (DrawRmovelist)
            {
                for (int i = 0; i < willremoveList.Count; ++i)
                {
                    Gizmos.color = Color.red;
                    Segment seg   = willremoveList [i];
                    KInt3   start = new KInt3(seg.start.x, 0, seg.start.y);
                    KInt3   end   = new KInt3(seg.end.x, 0, seg.end.y);
                    Gizmos.DrawLine(start, end);
                    UnityEditor.Handles.Label((start + end) / 2, "序号 [" + seg.uid + "]");
                }
            }

            if (Drawsegments)
            {
                for (int i = 0; i < segments.Count; ++i)
                {
                    Gizmos.color = (i % 2 == 0) ? Color.green : Color.blue;
                    Segment seg   = segments [i];
                    KInt3   start = new KInt3(seg.start.x, 0, seg.start.y);
                    KInt3   end   = new KInt3(seg.end.x, 0, seg.end.y);
                    Gizmos.DrawLine(start, end);
                    UnityEditor.Handles.Label((start + end) / 2, "序号 [" + seg.uid + "]");
                }
            }

            if (DrawNearstTriangles)
            {
                if (tree != null && lastpoint != targetPoint)
                {
                    if (SeekedTriangleList == null)
                    {
                        SeekedTriangleList = new List <NavmeshTriangle> ();
                    }

                    SeekedTriangleList.Clear();

                    List <KInt2> startidxs = ListPool.TrySpawn <List <KInt2> > ();
                    tree.ball_queryPoints((KInt2)targetPoint, Seekrange, startidxs);
                    for (int k = 0; k < startidxs.Count; ++k)
                    {
                        var trianglelist = point2triangle [startidxs [k]];
                        for (int v = 0; v < trianglelist.Count; ++v)
                        {
                            SeekedTriangleList.Add(trianglelist [v]);
                        }
                    }
                    ListPool.TryDespawn(startidxs);
                    lastpoint = targetPoint;
                }

                Gizmos.DrawWireCube(new Vector3(targetPoint.x, 0, targetPoint.y), Vector3.one);

                if (SeekedTriangleList != null)
                {
                    for (int i = 0; i < SeekedTriangleList.Count; i++)
                    {
                        NavmeshTriangle node = SeekedTriangleList [i];
                        Gizmos.color = Color.cyan;
                        for (int q = 0; q < node.connections.Count; q++)
                        {
                            Gizmos.DrawLine(node.averagePos, Vector3.Lerp(node.averagePos, node.connections [q].averagePos, 0.45f));
                        }

                        Gizmos.color = Color.black;
                        Gizmos.DrawLine(ObsVertices [node.v0], ObsVertices [node.v1]);
                        Gizmos.DrawLine(ObsVertices [node.v1], ObsVertices [node.v2]);
                        Gizmos.DrawLine(ObsVertices [node.v2], ObsVertices [node.v0]);

                        UnityEditor.Handles.Label(node.averagePos, "序号 [" + node.uid + "]");
                    }
                }
            }

            if (show)
            {
                for (int i = 0; i < ObsTriangles.Length; i++)
                {
                    NavmeshTriangle node = ObsTriangles [i];
                    Gizmos.color = Color.cyan;
                    for (int q = 0; q < node.connections.Count; q++)
                    {
                        Gizmos.DrawLine(node.averagePos, Vector3.Lerp(node.averagePos, node.connections [q].averagePos, 0.45f));
                    }

                    Gizmos.color = Color.black;
                    Gizmos.DrawLine(ObsVertices [node.v0], ObsVertices [node.v1]);
                    Gizmos.DrawLine(ObsVertices [node.v1], ObsVertices [node.v2]);
                    Gizmos.DrawLine(ObsVertices [node.v2], ObsVertices [node.v0]);
                }
            }
        }