Example #1
0
    /// <summary>
    /// 寻路数据转换为字符串
    /// </summary>
    /// <param name="mesh"></param>
    /// <returns></returns>
    private string PathMeshToString(UnityEngine.AI.NavMeshTriangulation mesh)
    {
        if (mesh.indices.Length < 1)
        {
            return("");
        }
        StringBuilder sb = new StringBuilder();

        sb.Append("\"pathTriangles\":[");
        for (int i = 0; i < mesh.indices.Length; i++)
        {
            sb.Append(mesh.indices[i]).Append(",");
        }
        sb.Length--;
        sb.Append("],");

        sb.Append("\"pathVertices\":[");
        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            Vector3 v = mesh.vertices[i];

            sb.Append("{\"x\":").Append(v.x).Append(",\"y\":").Append(v.y).Append(",\"z\":").Append(v.z).Append("},");
        }
        sb.Length--;
        sb.Append("]");
        return(sb.ToString());
    }
Example #2
0
 static public int constructor(IntPtr l)
 {
     try {
                     #if DEBUG
         var    method     = System.Reflection.MethodBase.GetCurrentMethod();
         string methodName = GetMethodName(method);
                     #if UNITY_5_5_OR_NEWER
         UnityEngine.Profiling.Profiler.BeginSample(methodName);
                     #else
         Profiler.BeginSample(methodName);
                     #endif
                     #endif
         UnityEngine.AI.NavMeshTriangulation o;
         o = new UnityEngine.AI.NavMeshTriangulation();
         pushValue(l, true);
         pushValue(l, o);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
             #if DEBUG
     finally {
                     #if UNITY_5_5_OR_NEWER
         UnityEngine.Profiling.Profiler.EndSample();
                     #else
         Profiler.EndSample();
                     #endif
     }
             #endif
 }
        public static void Triangulate(out Vector3[] vertices, out int[] indices)
        {
            NavMeshTriangulation results = CalculateTriangulation();

            vertices = results.vertices;
            indices  = results.indices;
        }
Example #4
0
    static void Build()
    {
        GameObject g  = new GameObject("navMesh");
        MeshFilter mf = g.AddComponent <MeshFilter>();

#if UNITY_5_5_OR_NEWER
        UnityEngine.AI.NavMeshTriangulation triangles = UnityEngine.AI.NavMesh.CalculateTriangulation();
#else
        UnityEngine.NavMeshTriangulation triangles = UnityEngine.NavMesh.CalculateTriangulation();
#endif
        Mesh mesh = new Mesh();
        mesh.vertices  = triangles.vertices;
        mesh.triangles = triangles.indices;
        Vector2[] uvs = new Vector2[mesh.vertices.Length];
        for (int i = 0; i < uvs.Length; i++)
        {
            uvs[i] = new Vector2(0f, 0f);
        }
        mesh.uv = uvs;
        mesh.RecalculateNormals();


        mf.mesh = mesh;
//		MeshRenderer mr= g.AddComponent<MeshRenderer>();
    }
        public static void Triangulate(out Vector3[] vertices, out int[] indices)
        {
            NavMeshTriangulation navMeshTriangulation = NavMesh.CalculateTriangulation();

            vertices = navMeshTriangulation.vertices;
            indices  = navMeshTriangulation.indices;
        }
    /// <summary>
    ///
    /// </summary>
    /// <param name="mesh"></param>
    /// <param name="type">0 阻挡 ;1行走;2安全</param>
    /// <returns></returns>
    static string MeshToString(UnityEngine.AI.NavMeshTriangulation mesh, int type)
    {
        if (mesh.indices.Length < 1)
        {
            return("");
        }

        StringBuilder sb = new StringBuilder();

        sb.Append(type == 0 ? "\"blockTriangles\":[" : (type == 1 ? "\"pathTriangles\":[" : "\"safeTriangles\":["));
        for (int i = 0; i < mesh.indices.Length; i++)
        {
            sb.Append(mesh.indices[i]).Append(",");
        }

        sb.Length--;
        sb.Append("],");

        sb.Append(type == 0 ? "\"blockVertices\":[" : (type == 1 ? "\"pathVertices\":[" : "\"safeVertices\":["));
        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            Vector3 v = mesh.vertices[i];
            if (type > 0 && v.y < 1)
            {
                Debug.LogWarning("寻路mesh坐标小于1" + v.y);
            }

            sb.Append("{\"x\":").Append(v.x).Append(",\"y\":").Append(type == 0 ? 0 : v.y).Append(",\"z\":").Append(v.z)
            .Append("},");
        }

        sb.Length--;
        sb.Append("]");
        return(sb.ToString());
    }
Example #7
0
        static string GenNavMeshOriginJson()
        {
            UnityEngine.AI.NavMeshTriangulation navtri = UnityEngine.AI.NavMesh.CalculateTriangulation();
            string outnav = "";

            outnav = "{\"v\":[\n";
            for (int i = 0; i < navtri.vertices.Length; i++)
            {
                if (i > 0)
                {
                    outnav += ",\n";
                }

                outnav += "[" + navtri.vertices[i].x + "," + navtri.vertices[i].y + "," + navtri.vertices[i].z + "]";
            }
            outnav += "\n],\"p\":[\n";

            for (int i = 0; i < navtri.indices.Length; i++)
            {
                if (i > 0)
                {
                    outnav += ",\n";
                }

                int index = navtri.indices[i];
                outnav += index.ToString();
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                sphere.name = "s" + index;
                sphere.transform.position = navtri.vertices[index];
            }
            outnav += "\n]}";
            return(outnav);
        }
Example #8
0
    /// \brief Converts a NavMesh (or a NavMesh area) into a standard Unity mesh.  This is later used
    ///        to render the mesh on-screen using Unity's standard rendering tools.
    ///
    /// \param navMesh Precalculated Nav Mesh Triangulation
    /// \param vert_size size of vertex array
    /// \param tri_size size of triangle array
    private static Mesh ConvertNavmeshToMesh(UnityEngine.AI.NavMeshTriangulation navMesh, int vert_size, int tri_size)
    {
        Mesh ret = new Mesh();

        if (vert_size >= 65535)
        {
            Debug.LogError("Playable NavMesh too big (vertex count >= 65535)!  Limit the size of the playable area using" +
                           "Area Masks.  For now no preview mesh will render.");
            return(ret);
        }

        Vector3[] vertices = new Vector3[vert_size];
        for (int x = 0; x < vertices.Length; x++)
        {
            // Note: Unity navmesh is offset 0.05m from the ground.  This pushes it down to 0
            vertices[x] = navMesh.vertices[x];
        }

        int[] triangles = new int[tri_size * 3];
        for (int x = 0; x < triangles.Length; x++)
        {
            triangles[x] = navMesh.indices[x];
        }

        ret.name      = "Navmesh";
        ret.vertices  = vertices;
        ret.triangles = triangles;

        RemoveMeshDuplicates(ret);

        ret.RecalculateNormals();
        ret.RecalculateBounds();

        return(ret);
    }
Example #9
0
    static void Export()
    {
        Debug.Log("NavMesh Export Start");
        UnityEngine.AI.NavMeshTriangulation navMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();
        //文件路径 路径文件夹不存在会报错
        string path = Application.dataPath + "/" + SceneManager.GetActiveScene().name + ".obj";
        //新建文件
        StreamWriter streamWriter = new StreamWriter(path);

        //顶点
        for (int i = 0; i < navMeshTriangulation.vertices.Length; i++)
        {
            streamWriter.WriteLine("v  " + navMeshTriangulation.vertices[i].x + " " + navMeshTriangulation.vertices[i].y + " " + navMeshTriangulation.vertices[i].z);
        }
        streamWriter.WriteLine("g pPlane1");
        //索引
        for (int i = 0; i < navMeshTriangulation.indices.Length;)
        {
            streamWriter.WriteLine("f " + (navMeshTriangulation.indices[i] + 1) + " " + (navMeshTriangulation.indices[i + 1] + 1) + " " + (navMeshTriangulation.indices[i + 2] + 1));
            i = i + 3;
        }
        streamWriter.Flush();
        streamWriter.Close();
        AssetDatabase.Refresh();
        Debug.Log("NavMesh Export Success");
    }
    /// <summary>
    /// 获取导航随机点
    /// </summary>
    /// <returns></returns>
    public Vector3 GetRandomLocation()
    {
        UnityEngine.AI.NavMeshTriangulation navMeshData = UnityEngine.AI.NavMesh.CalculateTriangulation();
        int     t     = Random.Range(0, navMeshData.indices.Length - 3);
        Vector3 point = Vector3.Lerp(navMeshData.vertices[navMeshData.indices[t]], navMeshData.vertices[navMeshData.indices[t + 1]], Random.value);

        point = Vector3.Lerp(point, navMeshData.vertices[navMeshData.indices[t + 2]], Random.value);
        return(point);
    }
Example #11
0
        /// <summary>
        /// Triangulate and return a mesh based on every NavMesh currently loaded.
        /// Unity's triangulation system is very broken, so triangulation works correctly only for flat NavMeshes (no slopes).
        /// </summary>
        public Mesh GetMesh()
        {
            NavMeshTriangulation navTriangulation = NavMesh.CalculateTriangulation();
            Mesh output = new Mesh();

            output.name      = "NavMeshTriangulated";
            output.vertices  = navTriangulation.vertices;
            output.triangles = navTriangulation.indices;
            return(output);
        }
Example #12
0
    /// <summary>
    /// 计算行走层三角网格
    /// </summary>
    /// <returns></returns>
    private UnityEngine.AI.NavMeshTriangulation Path()
    {
        ClearTemp();
        pathMesh.GetComponent <Renderer>().enabled = true;
        UnityEditor.AI.NavMeshBuilder.ClearAllNavMeshes();
        UnityEditor.AI.NavMeshBuilder.BuildNavMesh();
        UnityEngine.AI.NavMeshTriangulation triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();


        return(triangulatedNavMesh);
    }
 static public int constructor(IntPtr l)
 {
     try {
         UnityEngine.AI.NavMeshTriangulation o;
         o = new UnityEngine.AI.NavMeshTriangulation();
         pushValue(l, true);
         pushValue(l, o);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
Example #14
0
    static void Export()
    {
        UnityEngine.AI.NavMeshTriangulation triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();
        Mesh mesh = new Mesh();

        mesh.name     = "ExportedNavMesh";
        mesh.vertices = triangulatedNavMesh.vertices;
        int[] areas = triangulatedNavMesh.areas;
        mesh.triangles = triangulatedNavMesh.indices;
        string filename = Application.dataPath + "/" + Path.GetFileNameWithoutExtension(EditorApplication.currentScene) + ".obj";

        MeshToFile(mesh, areas, filename);
        print("NavMesh exported as '" + filename + "'");
        AssetDatabase.Refresh();
    }
Example #15
0
    static void Export()
    {
        Debug.Log("ExportNavMesh");

        UnityEngine.AI.NavMeshTriangulation tmpNavMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();


        list = new List <Cell>();

        //索引
        for (int i = 0; i < tmpNavMeshTriangulation.indices.Length;)
        {
            var cell = new Cell();
            cell.v[0]   = tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i]];
            cell.v[1]   = tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 1]];
            cell.v[2]   = tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 2]];
            cell.v[0].y = 0;
            cell.v[1].y = 0;
            cell.v[2].y = 0;
            cell.MidPos = (cell.v[0] + cell.v[1] + cell.v[2]) / 3;
            cell.MaxX   = GetMaxX(cell.v[0], cell.v[1], cell.v[2]);
            cell.MaxY   = GetMaxZ(cell.v[0], cell.v[1], cell.v[2]);
            cell.MinX   = GetMinX(cell.v[0], cell.v[1], cell.v[2]);
            cell.MinY   = GetMinZ(cell.v[0], cell.v[1], cell.v[2]);
            //cell.AreaSize = GetAreaSize(cell.v[0], cell.v[1], cell.v[2]);
            cell.index = list.Count;
            list.Add(cell);
            i = i + 3;
        }
        for (int i = 0; i < list.Count; i++)
        {
            var a = list[i];
            for (int j = 0; j < list.Count; j++)
            {
                var b = list[j];
                if (a != b)
                {
                    List <int> l = new List <int>();
                    if (IsNearCell(a, b, l))
                    {
                        InsertNears(a, b, j, l);
                    }
                }
            }
        }

        Debug.Log("ExportNavMesh Success");
    }
Example #16
0
    static void Export()
    {
        UnityEngine.AI.NavMeshTriangulation triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();
        Debug.Log(triangulatedNavMesh.vertices.ToString());

        Debug.Log(triangulatedNavMesh.indices.ToString());

        Mesh mesh = new Mesh();

        mesh.name      = "ExportedNavMesh";
        mesh.vertices  = triangulatedNavMesh.vertices;
        mesh.triangles = triangulatedNavMesh.indices;
        string filename = Application.dataPath + "/../../Server/data/" + Path.GetFileNameWithoutExtension(SceneManager.GetActiveScene().name) + ".NavMesh.obj";

        MeshToFile(mesh, filename);
        print("NavMesh exported as '" + filename + "'");
        AssetDatabase.Refresh();
    }
Example #17
0
    private static void Export()
    {
        UnityEngine.AI.NavMeshTriangulation triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();

        Mesh mesh = new Mesh();

        mesh.name      = "_NavMesh";
        mesh.vertices  = triangulatedNavMesh.vertices;
        mesh.triangles = triangulatedNavMesh.indices;

        string baseName = "navmesh_" + SceneManager.GetActiveScene().name;
        string fileName = Application.dataPath + "/navmesh/" + baseName + ".obj";

        ExportNavmesh(mesh, fileName);

        string     assetName = fileName.Replace(Application.dataPath, "Assets");
        GameObject navMesh   = Instantiate(AssetDatabase.LoadAssetAtPath <GameObject>(assetName));

        navMesh.name = baseName;
        ExportNavData(navMesh);
        Debug.Log("导出完成:" + baseName);
        AssetDatabase.Refresh();
    }
Example #18
0
    /// <summary>
    /// 创建网格数据
    /// </summary>
    private void CreatePolyNavMesh()
    {
        UnityEngine.AI.NavMeshTriangulation triangulatedWalkNavMesh = Path();
        string path = System.Environment.CurrentDirectory.Replace("\\", "/") + "/../Config/Nav_build/";

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        StringBuilder sb = new StringBuilder("{");

        sb.Append("\"mapID\":").Append(mapID);
        sb.Append(",\"startX\":").Append(startX).Append(",\"startZ\":").Append(startZ);
        sb.Append(",\"endX\":").Append(endX).Append(",\"endZ\":").Append(endZ);
        string filename = path + mapID + ".navmesh";

        string data = "";

        data = PathMeshToString(triangulatedWalkNavMesh);
        sb.Append(",").Append(data);
        sb.Append("}");
        MeshToFile(filename, sb.ToString());
    }
Example #19
0
    public static void ExportNavMesh()
    {
        Debug.Log("Export NavMesh");

        //Unity2017 API
        UnityEngine.AI.NavMeshTriangulation navMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();
        string sceneName = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().name;

        //新建文件
        string       savePath = Application.dataPath + "/" + sceneName + "_NavMesh.obj";
        StreamWriter sw       = new StreamWriter(savePath);

        //顶点
        for (int i = 0; i < navMeshTriangulation.vertices.Length; i++)
        {
            sw.WriteLine("v  " + navMeshTriangulation.vertices[i].x + " " + navMeshTriangulation.vertices[i].y + " " + navMeshTriangulation.vertices[i].z);
        }

        sw.WriteLine("g navmesh");//组名称

        //索引
        for (int i = 0; i < navMeshTriangulation.indices.Length;)
        {
            //obj文件中顶点索引是从1开始
            sw.WriteLine("f " + (navMeshTriangulation.indices[i] + 1) + " " + (navMeshTriangulation.indices[i + 1] + 1) + " " + (navMeshTriangulation.indices[i + 2] + 1));
            i = i + 3;
        }

        sw.Flush();
        sw.Close();

        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);

        Debug.Log(string.Format("Verts:{0}  Tris:{1}", navMeshTriangulation.vertices.Length, navMeshTriangulation.indices.Length / 3));
        Debug.Log(savePath);
        Debug.Log("ExportNavMesh Success");
    }
    void Awake()
    {
        draw = false;

        UnityEngine.AI.NavMeshTriangulation nav = UnityEngine.AI.NavMesh.CalculateTriangulation();
        navMesh           = new Mesh();
        navMesh.vertices  = nav.vertices;
        navMesh.triangles = nav.indices;

        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

        sphere.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
        wpMesh = sphere.GetComponent <MeshFilter>().mesh;

        Shader   s            = Shader.Find("Unlit/Color");
        Material lineMaterial = new Material(s);

        lineMaterial.hideFlags = HideFlags.HideAndDontSave;
        lineMaterial.color     = Color.blue;
        pathMaterial           = new Material(s);
        pathMaterial.hideFlags = HideFlags.HideAndDontSave;
        pathMaterial.color     = Color.red;

        lineRenderers = new List <GameObject> (navMesh.triangles.Length / 3);

        /*for (int i = 0; i < navMesh.triangles.Length; i += 3) {
         *      GameObject obj = new GameObject ("renderer");
         *      LineRenderer renderer = obj.AddComponent<LineRenderer>();
         *      renderer.useWorldSpace = true;
         *      renderer.SetWidth (0.01f, 0.01f);
         *      renderer.material = lineMaterial;
         *      renderer.SetVertexCount (3);
         *      for (int j = 0; j < 3; j++)
         *              renderer.SetPosition (j, navMesh.vertices [navMesh.triangles [i + j]] + 0.15f * Vector3.up);
         *      lineRenderers.Add (obj);
         * }*/
    }
Example #21
0
    public override void OnInspectorGUI()
    {
        GUIStyle bold_wrap = EditorStyles.boldLabel;

        bold_wrap.wordWrap = true;
        GUILayout.Label("Navmesh Preprocessor for HTC Vive Locomotion", bold_wrap);
        GUILayout.Label("Adrian Biagioli 2016", EditorStyles.miniLabel);

        GUILayout.Label("Before Using", bold_wrap);
        GUIStyle wrap = EditorStyles.label;

        wrap.wordWrap = true;
        GUILayout.Label(
            "Make sure you bake a Navigation Mesh (NavMesh) in Unity before continuing (Window > Navigation).  When you " +
            "are done, click \"Update Navmesh Data\" below.  This will update the graphic of the playable area " +
            "that the player will see in-game.\n",
            wrap);

        ViveNavMesh mesh = (ViveNavMesh)target;

        serializedObject.Update();

        // Area Mask //
        string[] areas      = GameObjectUtility.GetNavMeshAreaNames();
        int[]    area_index = new int[areas.Length];
        int      temp_mask  = 0;

        for (int x = 0; x < areas.Length; x++)
        {
            area_index[x] = GameObjectUtility.GetNavMeshAreaFromName(areas[x]);
            temp_mask    |= ((p_area.intValue >> area_index[x]) & 1) << x;
        }
        EditorGUI.BeginChangeCheck();
        temp_mask = EditorGUILayout.MaskField("Area Mask", temp_mask, areas);
        if (EditorGUI.EndChangeCheck())
        {
            p_area.intValue = 0;
            for (int x = 0; x < areas.Length; x++)
            {
                p_area.intValue |= (((temp_mask >> x) & 1) == 1 ? 0 : 1) << area_index[x];
            }
            p_area.intValue = ~p_area.intValue;
        }
        serializedObject.ApplyModifiedProperties();

        // Sanity check for Null properties //
        bool HasMesh = (mesh.SelectableMesh != null && mesh.SelectableMesh.vertexCount != 0) || (mesh.SelectableMeshBorder != null && mesh.SelectableMeshBorder.Length != 0);

        // Fixes below error message popping up with prefabs.  Kind of hacky but gets the job done
        bool isPrefab = EditorUtility.IsPersistent(target);

        if (isPrefab && mesh.SelectableMesh == null)
        {
            mesh.SelectableMesh = new Mesh();
        }

        bool MeshNull   = mesh.SelectableMesh == null;
        bool BorderNull = mesh.SelectableMeshBorder == null;

        if (MeshNull || BorderNull)
        {
            string str = "Internal Error: ";
            if (MeshNull)
            {
                str += "Selectable Mesh == null.  ";
            }
            if (BorderNull)
            {
                str += "Border point array == null.  ";
            }
            str += "This may lead to strange behavior or serialization.  Try updating the mesh or delete and recreate the Navmesh object.  ";
            str += "If you are able to consistently get a Vive Nav Mesh object into this state, please submit a bug report.";
            EditorGUILayout.HelpBox(str, MessageType.Error);
        }

        // Update / Clear Navmesh Data //
        if (GUILayout.Button("Update Navmesh Data"))
        {
            Undo.RecordObject(mesh, "Update Navmesh Data");

            UnityEngine.AI.NavMeshTriangulation tri = UnityEngine.AI.NavMesh.CalculateTriangulation();
            int vert_size, tri_size;
            CullNavmeshTriangulation(ref tri, p_area.intValue, out vert_size, out tri_size);

            Mesh m = ConvertNavmeshToMesh(tri, vert_size, tri_size);
            // Can't use SerializedProperties here because BorderPointSet doesn't derive from UnityEngine.Object
            mesh.SelectableMeshBorder = FindBorderEdges(m);

            serializedObject.Update();
            p_mesh.objectReferenceValue = m;
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.SelectableMesh = mesh.SelectableMesh; // Make sure that setter is called
        }

        GUI.enabled = HasMesh;
        if (GUILayout.Button("Clear Navmesh Data"))
        {
            Undo.RecordObject(mesh, "Clear Navmesh Data");

            // Note: Unity does not serialize "null" correctly so we set everything to empty objects
            Mesh m = new Mesh();

            serializedObject.Update();
            p_mesh.objectReferenceValue = m;
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.SelectableMesh = mesh.SelectableMesh; // Make sure setter is called

            mesh.SelectableMeshBorder = new BorderPointSet[0];
        }
        GUI.enabled = true;

        GUILayout.Label(HasMesh ? "Status: NavMesh Loaded" : "Status: No NavMesh Loaded");

        // Render Settings //
        EditorGUILayout.LabelField("Render Settings", EditorStyles.boldLabel);

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(p_material);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(mesh, "Change Ground Material");
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.GroundMaterial = mesh.GroundMaterial; // Reload material
        }

        EditorGUILayout.PropertyField(p_alpha);
        serializedObject.ApplyModifiedProperties();
    }
Example #22
0
    /// \brief Modifies the given NavMesh so that only the Navigation areas are present in the mesh.  This is done only
    ///        by swapping, so that no new memory is allocated.
    ///
    /// The data stored outside of the returned array sizes should be considered invalid and will contain garbage data.
    /// \param navMesh NavMesh data to modify
    /// \param area Area mask to include in returned mesh.  Areas outside of this mask are culled.
    /// \param vert_size New size of navMesh.vertices
    /// \param tri_size New size of navMesh.areas and one third of the size of navMesh.indices
    private static void CullNavmeshTriangulation(ref UnityEngine.AI.NavMeshTriangulation navMesh, int area, out int vert_size, out int tri_size)
    {
        // Step 1: re-order triangles so that valid areas are in front.  Then determine tri_size.
        tri_size = navMesh.indices.Length / 3;
        for (int i = 0; i < tri_size; i++)
        {
            Vector3 p1       = navMesh.vertices[navMesh.indices[i * 3]];
            Vector3 p2       = navMesh.vertices[navMesh.indices[i * 3 + 1]];
            Vector3 p3       = navMesh.vertices[navMesh.indices[i * 3 + 2]];
            Plane   p        = new Plane(p1, p2, p3);
            bool    vertical = Mathf.Abs(Vector3.Dot(p.normal, Vector3.up)) > 0.99f;

            // If the current triangle isn't flat (normal is up) or if it doesn't match
            // with the provided mask, we should cull it.
            if (((1 << navMesh.areas[i]) & area) == 0 || !vertical) // If true this triangle should be culled.
            {
                // Swap area indices and triangle indices with the end of the array
                int t_ind = tri_size - 1;

                int t_area = navMesh.areas[t_ind];
                navMesh.areas[t_ind] = navMesh.areas[i];
                navMesh.areas[i]     = t_area;

                for (int j = 0; j < 3; j++)
                {
                    int t_v = navMesh.indices[t_ind * 3 + j];
                    navMesh.indices[t_ind * 3 + j] = navMesh.indices[i * 3 + j];
                    navMesh.indices[i * 3 + j]     = t_v;
                }

                // Then reduce the size of the array, effectively cutting off the previous triangle
                tri_size--;
                // Stay on the same index so that we can check the triangle we just swapped.
                i--;
            }
        }

        // Step 2: Cull the vertices that aren't used.
        vert_size = 0;
        for (int i = 0; i < tri_size * 3; i++)
        {
            int prv = navMesh.indices[i];
            if (prv >= vert_size)
            {
                int nxt = vert_size;

                // Bring the current vertex to the end of the "active" array by swapping it with what's currently there
                Vector3 t_v = navMesh.vertices[prv];
                navMesh.vertices[prv] = navMesh.vertices[nxt];
                navMesh.vertices[nxt] = t_v;

                // Now change around the values in the triangle indices to reflect the swap
                for (int j = i; j < tri_size * 3; j++)
                {
                    if (navMesh.indices[j] == prv)
                    {
                        navMesh.indices[j] = nxt;
                    }
                    else if (navMesh.indices[j] == nxt)
                    {
                        navMesh.indices[j] = prv;
                    }
                }

                // Increase the size of the vertex array to reflect the changes.
                vert_size++;
            }
        }
    }
Example #23
0
        //TODO: 导出area字段
        static string GenNavMesh(string style)
        {
            float progress  = 0;
            float detailPro = 0;

            EditorUtility.DisplayProgressBar(ProgressBarName, "获取NavMesh三角形数据", progress);
            // return GenNavMeshOriginJson();
            UnityEngine.AI.NavMeshTriangulation navtri = UnityEngine.AI.NavMesh.CalculateTriangulation();
            //{
            //    var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
            //    var mf = obj.GetComponent<MeshFilter>();
            //    Mesh m = new Mesh();
            //    m.vertices = navtri.vertices;
            //    m.triangles = navtri.indices;
            //    mf.mesh = m;
            //}
            Dictionary <int, int> indexmap = new Dictionary <int, int>();
            List <Vector3>        repos    = new List <Vector3>();

            progress += 0.1f;
            float mergeSameVertexSumPro = 0.1f;

            for (int i = 0; i < navtri.vertices.Length; i++)
            {
                detailPro = (progress + mergeSameVertexSumPro * (i + 1) / navtri.vertices.Length);
                EditorUtility.DisplayProgressBar(ProgressBarName, "合并相同顶点(" + (i + 1) + "/" + navtri.vertices.Length + ")", detailPro);
                int ito = -1;
                for (int j = 0; j < repos.Count; j++)
                {
                    if (Vector3.Distance(navtri.vertices[i], repos[j]) < 0.01)
                    {
                        ito = j;
                        break;
                    }
                }
                if (ito < 0)
                {
                    indexmap[i] = repos.Count;
                    repos.Add(navtri.vertices[i]);
                }
                else
                {
                    indexmap[i] = ito;
                }
            }
            progress  = detailPro;
            detailPro = 0.0f;
            // for(int i=0; i<navtri.areas.Length; i++)
            //     Debug.Log("area : "+navtri.areas[i].ToString());
            //关系是 index 公用的三角形表示他们共同组成多边形
            //多边形之间的连接用顶点位置识别
            List <int> polylast = new List <int>();
            // List<int[]> polys = new List<int[]>();
            List <List <int> > polys = new List <List <int> >();

            MaxVertexPerPoly = 6;
            float makePolySumPro = 0.1f;

            for (int i = 0; i < navtri.indices.Length / 3; i++)
            {
                detailPro = progress + makePolySumPro * i / navtri.indices.Length / 3;
                EditorUtility.DisplayProgressBar(ProgressBarName, "合并邻近三角形(" + i + "/" + (navtri.indices.Length / 3) + ")", detailPro);
                int i0 = navtri.indices[i * 3 + 0];
                int i1 = navtri.indices[i * 3 + 1];
                int i2 = navtri.indices[i * 3 + 2];
                // i0 = indexmap[i0];
                // i1 = indexmap[i1];
                // i2 = indexmap[i2];
                if (polylast.Contains(i0) || polylast.Contains(i1) || polylast.Contains(i2))
                {
                    if (polylast.Contains(i0) == false)
                    {
                        polylast.Add(i0);
                    }
                    if (polylast.Contains(i1) == false)
                    {
                        polylast.Add(i1);
                    }
                    if (polylast.Contains(i2) == false)
                    {
                        polylast.Add(i2);
                    }
                }
                else
                {
                    if (polylast.Count > 0)
                    {
                        AddPolyByVertex(polylast, ref polys, style == "json");
                    }
                    polylast.Clear();
                    polylast.Add(i0);
                    polylast.Add(i1);
                    polylast.Add(i2);
                }
            }
            if (polylast.Count > 0)
            {
                AddPolyByVertex(polylast, ref polys, style == "json");
            }
            progress  = detailPro;
            detailPro = 0.0f;
            string outnav = "";

            if (style == "json")
            {
                for (int i = 0; i < polys.Count; i++)
                {
                    for (int j = 0; j < polys[i].Count; j++)
                    {
                        if (polys[i][j] != NullIndex)
                        {
                            polys[i][j] = indexmap[polys[i][j]];
                        }
                    }
                    for (int ii = polys[i].Count; ii < MaxVertexPerPoly; ii++)
                    {
                        polys[i].Add(NullIndex);
                    }
                }
                List <List <int> > neighbor = new List <List <int> >();
                GenNeighbor(polys, ref neighbor, progress);
                progress += 0.1f;
                MergePolyAndNeighbor(ref polys, neighbor);
                float[] boundsMin = new float[3];
                float[] boundsMax = new float[3];
                EditorUtility.DisplayProgressBar(ProgressBarName, "反转所有顶点X轴", progress += 0.1f);
                RevertX(ref repos);
                EditorUtility.DisplayProgressBar(ProgressBarName, "计算包围盒", progress += 0.1f);
                GetBounds(repos, ref boundsMin, ref boundsMax);
                // Debug.Log("max bounds :" + boundsMax[1].ToString()+" boundsMin:"+boundsMin[1].ToString());
                for (int i = 0; i < repos.Count; i++)
                {
                    ushort x = (ushort)Math.Round((repos[i].x - boundsMin[0]) / xzCellSize);
                    ushort y = (ushort)Math.Round((repos[i].y - boundsMin[1]) / yCellSize);
                    ushort z = (ushort)Math.Round((repos[i].z - boundsMin[2]) / xzCellSize);
                    repos[i] = new Vector3(x, y, z);
                }

                outnav  = "{";
                outnav += "\"nvp\":" + MaxVertexPerPoly + ",\n";
                outnav += "\"cs\":" + xzCellSize + ",\n";
                outnav += "\"ch\":" + yCellSize + ",\n";
                NavMeshBuildSettings settings = NavMesh.GetSettingsByIndex(0);
                outnav += "\"agentHeight\":" + settings.agentHeight + ",\n";
                outnav += "\"agentRadius\":" + settings.agentRadius + ",\n";
                outnav += "\"agentMaxClimb\":" + settings.agentClimb + ",\n";
                outnav += "\"bmin\":[" + boundsMin[0] + ", " + boundsMin[1] + ", " + boundsMin[2] + "],\n";
                outnav += "\"bmax\":[" + boundsMax[0] + ", " + boundsMax[1] + ", " + boundsMax[2] + "],\n";
                outnav += "\"v\":[\n";
                // List<List<uint>> vertexes = new List<List<uint>>();
                detailPro = 0.0f;
                for (int i = 0; i < repos.Count; i++)
                {
                    detailPro = progress + 0.1f * (i + 1) / repos.Count;
                    EditorUtility.DisplayProgressBar(ProgressBarName, "生成json顶点数据(" + (i + 1) + "/" + repos.Count + ")", detailPro);
                    // List<uint> vertex = new List<uint>();
                    // vertex.Add((uint)repos[i].x);
                    // vertex.Add((uint)repos[i].y);
                    // vertex.Add((uint)repos[i].z);
                    // vertexes.Add(vertex);
                    if (i > 0)
                    {
                        outnav += ",\n";
                    }
                    outnav += "[" + (repos[i].x) + "," + repos[i].y + "," + repos[i].z + "]";
                }
                outnav   += "\n],\n\"p\":[\n";
                progress  = detailPro;
                detailPro = 0.0f;
                for (int i = 0; i < polys.Count; i++)
                {
                    detailPro = progress + 0.1f * (i + 1) / polys.Count;
                    EditorUtility.DisplayProgressBar(ProgressBarName, "生成json多边形数据(" + (i + 1) + "/" + polys.Count + ")", detailPro);
                    // string outs = indexmap[polys[i][0]].ToString();
                    string outs = polys[i][0].ToString();
                    for (int j = 1; j < MaxVertexPerPoly; j++)
                    {
                        var verIndex = polys[i][j];
                        // if (verIndex!=NullIndex)
                        // verIndex = indexmap[verIndex];
                        outs += "," + verIndex;
                    }
                    for (int j = MaxVertexPerPoly; j < MaxVertexPerPoly * 2; j++)
                    {
                        outs += "," + polys[i][j];
                    }
                    if (i > 0)
                    {
                        outnav += ",\n";
                    }
                    outnav += "[" + outs + "]";
                }
                outnav += "\n]}";
                // Debug.Log("outnav : "+outnav);
            }
            else if (style == "obj")
            {
                detailPro = 0.0f;
                outnav    = "";
                for (int i = 0; i < repos.Count; i++)
                {//unity 对obj 做了 x轴 -1
                    detailPro = progress + 0.4f * (i + 1) / polys.Count;
                    EditorUtility.DisplayProgressBar(ProgressBarName, "生成json顶点数据(" + (i + 1) + "/" + repos.Count + ")", detailPro);
                    outnav += "v " + (repos[i].x * -1) + " " + repos[i].y + " " + repos[i].z + "\r\n";
                    // outnav += "v " + (repos[i].x) + " " + repos[i].y + " " + repos[i].z + "\r\n";
                }
                outnav   += "\r\n";
                progress  = detailPro;
                detailPro = 0.0f;
                for (int i = 0; i < polys.Count; i++)
                {
                    detailPro = progress + 0.5f * (i + 1) / polys.Count;
                    EditorUtility.DisplayProgressBar(ProgressBarName, "生成json多边形数据(" + (i + 1) + "/" + polys.Count + ")", detailPro);
                    outnav += "f";
                    //逆向
                    for (int j = polys[i].Count - 1; j >= 0; j--)
                    // for (int j = 0; j < polys[i].Count; j++)
                    {
                        outnav += " " + (indexmap[polys[i][j]] + 1);
                    }
                    outnav += "\r\n";
                }
            }
            return(outnav);
        }
Example #24
0
    /// <summary>
    /// 创建navmesh数据
    /// </summary>
    void CreateNavMeshData()
    {
        lock (this)
        {
            map.SetActive(false);
            xingzouceng.GetComponent <Renderer>().enabled = false;
            UnityEngine.AI.NavMeshTriangulation triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();
            GameObject WalkAble     = createOb("NavMesh_WalkAble", 1);
            Vector3[]  pathVertices = triangulatedNavMesh.vertices;
            int[]      triangles    = triangulatedNavMesh.indices;
            Mesh       WalkMesh     = WalkAble.GetComponent <MeshFilter>().sharedMesh;
            Vector3[]  vertexes     = new Vector3[pathVertices.Length];
            for (int i = 0; i < pathVertices.Length; i++)
            {
                float x = pathVertices[i].x;
                float z = pathVertices[i].z;
                vertexes[i] = new Vector3(x, 0, z);
            }
            WalkMesh.vertices  = vertexes;
            WalkMesh.triangles = triangles;

            GameObject UnWalkAble = createOb("NavMesh_UnWalkAble", 0);
            Mesh       UnWalkMesh = UnWalkAble.GetComponent <MeshFilter>().sharedMesh;
            UnWalkMesh.vertices = new Vector3[] {
                new Vector3(property.startX, 0, property.startZ),
                new Vector3(property.startX, 0, property.endZ),
                new Vector3(property.endX, 0, property.endZ),
                new Vector3(property.endX, 0, property.startZ)
            };
            UnWalkMesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 };
            SetAgentRadius(0.3f);
            UnityEditor.AI.NavMeshBuilder.ClearAllNavMeshes();
            UnityEditor.AI.NavMeshBuilder.BuildNavMesh();
            Object.DestroyImmediate(WalkAble);
            Object.DestroyImmediate(UnWalkAble);
            string path = System.Environment.CurrentDirectory.Replace("\\", "/") + "/Nav_build/";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            StringBuilder sb = new StringBuilder("{");
            sb.Append("\"mapID\":").Append(mapID);
            sb.Append(",\"startX\":").Append(property.startX).Append(",\"startZ\":").Append(property.startZ);
            sb.Append(",\"endX\":").Append(property.endX).Append(",\"endZ\":").Append(property.endZ);
            string filename = path + mapID + ".navmesh";
            triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();
            string data = MeshToString(triangulatedNavMesh, 0);
            if (data.Length < 128)
            {
                alert("阻挡未打入!");
                return;
            }
            sb.Append(",").Append(data);


            if (data.Length > 0)
            {
                sb.Append(",").Append(data);
            }

            BuildFloorNavMesh(property.agentRadius);
            triangulatedNavMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();
            data = MeshToString(triangulatedNavMesh, 1);
            if (data.Length < 128)
            {
                alert("寻路未打入!");
                return;
            }
            sb.Append(",").Append(data).Append("}");
            MeshToFile(filename, sb.ToString());
            BuildAllNavMesh(property.agentRadius);
            map.SetActive(true);
            alert("成功!");

            EditorSceneManager.SaveOpenScenes();
        }
        //Close();
    }
Example #25
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="style">0 json 1 obj</param>
    /// <returns></returns>
    string GenNavMesh(int style)
    {
        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
        UnityEngine.AI.NavMeshTriangulation navtri = UnityEngine.AI.NavMesh.CalculateTriangulation();

        //{
        //    var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
        //    var mf = obj.GetComponent<MeshFilter>();
        //    Mesh m = new Mesh();
        //    m.vertices = navtri.vertices;
        //    m.triangles = navtri.indices;
        //    mf.mesh = m;
        //}



        Dictionary <int, int> indexmap = new Dictionary <int, int>();
        List <Vector3>        repos    = new List <Vector3>();

        for (int i = 0; i < navtri.vertices.Length; i++)
        {
            int ito = -1;
            for (int j = 0; j < repos.Count; j++)
            {
                if (Vector3.Distance(navtri.vertices[i], repos[j]) < 0.01)
                {
                    ito = j;
                    break;
                }
            }
            if (ito < 0)
            {
                indexmap[i] = repos.Count;
                repos.Add(navtri.vertices[i]);
            }
            else
            {
                indexmap[i] = ito;
            }
        }

        //关系是 index 公用的三角形表示他们共同组成多边形
        //多边形之间的连接用顶点位置识别
        List <int>   polylast = new List <int>();
        List <int[]> polys    = new List <int[]>();

        List <int> areas = new List <int>();

        int lastArea = int.MaxValue;

        for (int i = 0; i < navtri.indices.Length / 3; i++)
        {
            int i0 = navtri.indices[i * 3 + 0];
            int i1 = navtri.indices[i * 3 + 1];
            int i2 = navtri.indices[i * 3 + 2];

            if ((polylast.Contains(i0) || polylast.Contains(i1) || polylast.Contains(i2)) && lastArea == navtri.areas[i])
            {
                if (polylast.Contains(i0) == false)
                {
                    polylast.Add(i0);
                }
                if (polylast.Contains(i1) == false)
                {
                    polylast.Add(i1);
                }
                if (polylast.Contains(i2) == false)
                {
                    polylast.Add(i2);
                }
            }
            else
            {
                if (polylast.Count > 0)
                {
                    polys.Add(polylast.ToArray());
                    areas.Add(lastArea);
                }
                polylast.Clear();
                polylast.Add(i0);
                polylast.Add(i1);
                polylast.Add(i2);
                lastArea = navtri.areas[i];
            }
        }
        if (polylast.Count > 0)
        {
            polys.Add(polylast.ToArray());
        }

        System.Text.StringBuilder outnav = new System.Text.StringBuilder();
        if (style == 0)
        {
            outnav.Append("{\"v\":[\n");
            for (int i = 0; i < repos.Count; i++)
            {
                if (i > 0)
                {
                    outnav.Append(",\n");
                }

                outnav.Append("[").Append(repos[i].x).Append(",").Append(repos[i].y).Append(",").Append(repos[i].z).Append("]");
            }
            outnav.Append("\n],\"p\":[\n");

            for (int i = 0; i < polys.Count; i++)
            {
                string outs = indexmap[polys[i][0]].ToString();
                for (int j = 1; j < polys[i].Length; j++)
                {
                    outs += "," + indexmap[polys[i][j]];
                }

                if (i > 0)
                {
                    outnav.Append(",\n");
                }

                outnav.Append("[").Append(outs).Append("]");
            }
            outnav.Append("\n]}");
        }
        else if (style == 1)
        {
            for (int i = 0; i < repos.Count; i++)
            {//unity 对obj 做了 x轴 -1
                outnav.Append("v ").Append(repos[i].x * -1).Append(" ").Append(repos[i].y).Append(" ").Append(repos[i].z).Append("\r\n");
            }
            outnav.Append("\r\n");
            for (int i = 0; i < polys.Count; i++)
            {
                outnav.Append("f");
                //逆向
                for (int j = polys[i].Length - 1; j >= 0; j--)
                {
                    outnav.Append(" ").Append(indexmap[polys[i][j]] + 1);
                }

                outnav.Append("\r\n");
            }
        }
        else if (style == 2)
        {
            outnav.Append("v\n");
            for (int i = 0; i < repos.Count; i++)
            {
                outnav.Append(repos[i].x).Append(" ").Append(repos[i].y).Append(" ").Append(repos[i].z).Append("\n");
            }

            int maxVertPerPoly = 0;
            outnav.Append("p\n");
            for (int i = 0; i < polys.Count; i++)
            {
                outnav.Append(indexmap[polys[i][0]]);
                for (int j = 1; j < polys[i].Length; j++)
                {
                    outnav.Append(" ").Append(indexmap[polys[i][j]]);
                }

                outnav.Append("\n");

                maxVertPerPoly = System.Math.Max(maxVertPerPoly, polys[i].Length);
            }

            //outnav.Append("a\n");
            //for (int i = 0; i < areas.Count; ++i)
            //{
            //    outnav.Append(areas[i]).Append("\n");
            //}

            outnav.Append("nvp\n").Append(maxVertPerPoly).Append("\n");
        }

        return(outnav.ToString());
    }
Example #26
0
    static void Export()
    {
        Debug.Log("ExportNavMesh");

        UnityEngine.AI.NavMeshTriangulation tmpNavMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();
        GtMsg.NavData navData = new GtMsg.NavData();


        list    = new List <Cell>();
        posList = new List <PosData>();
        //初始化每个cell的点
        for (int i = 0; i < tmpNavMeshTriangulation.indices.Length;)
        {
            var cell = new Cell();
            var v0   = tmpNavMeshTriangulation.indices[i];
            var v1   = tmpNavMeshTriangulation.indices[i + 1];
            var v2   = tmpNavMeshTriangulation.indices[i + 2];

            cell.v[0]   = CommonFunc.Round(tmpNavMeshTriangulation.vertices[v0]);
            cell.v[1]   = CommonFunc.Round(tmpNavMeshTriangulation.vertices[v1]);
            cell.v[2]   = CommonFunc.Round(tmpNavMeshTriangulation.vertices[v2]);
            cell.v[0].y = 0;
            cell.v[1].y = 0;
            cell.v[2].y = 0;


            //cell.vNormal[0] = new Vector3[2];
            //cell.vNormal[0][0] = Vector3.Normalize(cell.v[0] - cell.v[1]);
            //cell.vNormal[0][1] = Vector3.Normalize(cell.v[0] - cell.v[2]);

            //cell.vNormal[1][0] = Vector3.Normalize(cell.v[1] - cell.v[0]);
            //cell.vNormal[1][1] = Vector3.Normalize(cell.v[1] - cell.v[2]);

            //cell.vNormal[2][0] = Vector3.Normalize(cell.v[2] - cell.v[1]);
            //cell.vNormal[2][1] = Vector3.Normalize(cell.v[2] - cell.v[0]);

            //cell.MaxX = GetMaxX(cell.v[0], cell.v[1], cell.v[2]);
            //cell.MaxY = GetMaxZ(cell.v[0], cell.v[1], cell.v[2]);
            //cell.MinX = GetMinX(cell.v[0], cell.v[1], cell.v[2]);
            //cell.MinY = GetMinZ(cell.v[0], cell.v[1], cell.v[2]);
            //cell.AreaSize = GetAreaSize(cell.v[0], cell.v[1], cell.v[2]);
            //cell.index = list.Count;
            list.Add(cell);

            i = i + 3;
        }

        //处理不合格的cell
        int Count = 0;

        for (int i = 0; i < list.Count; i++)
        {
            var a = list[i];
            if (a.tobeRemove)
            {
                continue;
            }
            for (int j = 0; j < list.Count; j++)
            {
                var b = list[j];
                if (b.tobeRemove)
                {
                    continue;
                }
                if (a != b)
                {
                    var a0 = a.v[0];
                    var a1 = a.v[1];
                    var a2 = a.v[2];

                    var b0 = b.v[0];
                    var b1 = b.v[1];
                    var b2 = b.v[2];

                    int index = -1;
                    int vx1   = -1;
                    int vx2   = -1;
                    if (CommonFunc.PointInVector2(a0, a1, b0))
                    {
                        index = 0;
                        vx1   = 0;
                        vx2   = 1;
                    }
                    else if (CommonFunc.PointInVector2(a1, a2, b0))
                    {
                        index = 0;
                        vx1   = 1;
                        vx2   = 2;
                    }
                    else if (CommonFunc.PointInVector2(a2, a0, b0))
                    {
                        index = 0;
                        vx1   = 2;
                        vx2   = 0;
                    }
                    else if (CommonFunc.PointInVector2(a0, a1, b1))
                    {
                        index = 1;
                        vx1   = 0;
                        vx2   = 1;
                    }
                    else if (CommonFunc.PointInVector2(a1, a2, b1))
                    {
                        index = 1;
                        vx1   = 1;
                        vx2   = 2;
                    }
                    else if (CommonFunc.PointInVector2(a2, a0, b1))
                    {
                        index = 1;
                        vx1   = 2;
                        vx2   = 0;
                    }
                    else if (CommonFunc.PointInVector2(a0, a1, b2))
                    {
                        index = 2;
                        vx1   = 0;
                        vx2   = 1;
                    }
                    else if (CommonFunc.PointInVector2(a1, a2, b2))
                    {
                        index = 2;
                        vx1   = 1;
                        vx2   = 2;
                    }
                    else if (CommonFunc.PointInVector2(a2, a0, b2))
                    {
                        index = 2;
                        vx1   = 2;
                        vx2   = 0;
                    }

                    if (index != -1)
                    {
                        testList = GetCellByPoint(b.v[index]);

                        var length1 = Vector3.SqrMagnitude(b.v[index] - a.v[vx1]);
                        var length2 = Vector3.SqrMagnitude(b.v[index] - a.v[vx2]);

                        Vector3 pp;

                        if (length1 > length2)
                        {
                            pp = a.v[vx2];
                        }
                        else
                        {
                            pp = a.v[vx1];
                        }

                        foreach (var tt in testList)
                        {
                            bool bb = IsCellPoint(tt, pp);
                            //
                            if (bb)
                            {
                                //删除小三角形
                                //list.Remove(tt);
                                tt.tobeRemove = true;
                                Count++;
                            }
                            else
                            {
                                //扩张大三角形
                                for (int k = 0; k < 3; k++)
                                {
                                    if (tt.v[k].Equals(b.v[index]))
                                    {
                                        tt.v[k] = pp;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //设置cell的属性
        Debug.Log(Count);
        List <Cell> listtemp = new List <Cell>();

        for (int k = 0; k < list.Count; k++)
        {
            var cell = list[k];
            if (!cell.tobeRemove)
            {
                for (int i = 0; i < 3; i++)
                {
                    int posIndex = -1;
                    for (int j = 0; j < posList.Count; j++)
                    {
                        var v = posList[j];
                        if (v.Pos.Equals(cell.v[i]))
                        {
                            posIndex = j;
                            break;
                        }
                    }
                    if (posIndex == -1)
                    {
                        posList.Add(new PosData {
                            Pos = cell.v[i]
                        });
                        navData.PosList.Add(new GtMsg.PosData {
                            Pos = CommonFunc.GetVec3(cell.v[i])
                        });
                        posIndex = posList.Count - 1;
                    }
                    cell.vIndex[i] = posIndex;
                    posList[posIndex].CellIndexs.Add(k);
                    navData.PosList[posIndex].CellIndexs.Add(k);
                }


                cell.LineMidPos[0] = CommonFunc.Round((cell.v[0] + cell.v[1]) / 2);
                cell.LineMidPos[1] = CommonFunc.Round((cell.v[1] + cell.v[2]) / 2);
                cell.LineMidPos[2] = CommonFunc.Round((cell.v[2] + cell.v[0]) / 2);

                cell.Normalize[0] = Vector3.Normalize(cell.v[1] - cell.v[0]);
                cell.Normalize[1] = Vector3.Normalize(cell.v[2] - cell.v[1]);
                cell.Normalize[2] = Vector3.Normalize(cell.v[0] - cell.v[2]);


                cell.LineMidSqrDistance[0] = CommonFunc.Round(GetLineMidDstance(cell.v[0], cell.v[1], cell.v[2]));
                cell.LineMidSqrDistance[1] = CommonFunc.Round(GetLineMidDstance(cell.v[1], cell.v[0], cell.v[2]));
                cell.LineMidSqrDistance[2] = CommonFunc.Round(GetLineMidDstance(cell.v[2], cell.v[0], cell.v[1]));
                cell.MidPos = (cell.v[0] + cell.v[1] + cell.v[2]) / 3;

                listtemp.Add(cell);
                GtMsg.Cell msg_cell = new GtMsg.Cell();
                msg_cell.V.Add(CommonFunc.GetVec3(cell.v[0]));
                msg_cell.V.Add(CommonFunc.GetVec3(cell.v[1]));
                msg_cell.V.Add(CommonFunc.GetVec3(cell.v[2]));
                msg_cell.VIndex.Add(cell.vIndex[0]);
                msg_cell.VIndex.Add(cell.vIndex[1]);
                msg_cell.VIndex.Add(cell.vIndex[2]);


                msg_cell.MidPos = CommonFunc.GetVec3(cell.MidPos);
                msg_cell.Index  = navData.Celllist.Count;
                msg_cell.LineMidSqrDistance.Add(cell.LineMidSqrDistance[0]);
                msg_cell.LineMidSqrDistance.Add(cell.LineMidSqrDistance[1]);
                msg_cell.LineMidSqrDistance.Add(cell.LineMidSqrDistance[2]);
                msg_cell.LineMidPos.Add(CommonFunc.GetVec3(cell.LineMidPos[0]));
                msg_cell.LineMidPos.Add(CommonFunc.GetVec3(cell.LineMidPos[1]));
                msg_cell.LineMidPos.Add(CommonFunc.GetVec3(cell.LineMidPos[2]));
                msg_cell.Normalize.Add(CommonFunc.GetVec3(cell.Normalize[0]));
                msg_cell.Normalize.Add(CommonFunc.GetVec3(cell.Normalize[1]));
                msg_cell.Normalize.Add(CommonFunc.GetVec3(cell.Normalize[2]));
                for (int i = 0; i < 3; i++)
                {
                    GtMsg.Nears n = new GtMsg.Nears();
                    n.Enable = false;
                    msg_cell.Nears.Add(n);
                }

                cell.index = msg_cell.Index;
                navData.Celllist.Add(msg_cell);
            }
        }
        list = listtemp;

        //设置相邻cell
        for (int i = 0; i < list.Count; i++)
        {
            var a = list[i];
            for (int j = 0; j < list.Count; j++)
            {
                var b = list[j];
                if (a != b)
                {
                    int aLineIndex = -1;
                    int bLineIndex = -1;

                    if (IsNearCell(a, b, ref aLineIndex, ref bLineIndex))
                    {
                        var a2 = navData.Celllist[i];
                        InsertNears(a, b, a2, aLineIndex, bLineIndex);
                    }
                }
            }
        }

        string resourcePath = Application.dataPath + "/Resources/File/";

        if (!Directory.Exists(resourcePath))
        {
            Directory.CreateDirectory(resourcePath);
        }


        using (FileStream output = File.Create(resourcePath + "NavMesh.bytes"))
        {
            navData.WriteTo(output);
        }
        AssetDatabase.Refresh();
        EditorUtility.DisplayDialog("加载地图网格", "加载成功", "关闭");


        Debug.Log("ExportNavMesh Success");
    }
Example #27
0
    void GenNavMesh(string outfile)
    {
        UnityEngine.AI.NavMeshTriangulation navtri = UnityEngine.AI.NavMesh.CalculateTriangulation();
        Dictionary <int, int> indexmap             = new Dictionary <int, int>();
        List <Vector3>        repos = new List <Vector3>();

        for (int i = 0; i < navtri.vertices.Length; i++)
        {
            int ito = -1;
            for (int j = 0; j < repos.Count; j++)
            {
                if (Vector3.Distance(navtri.vertices[i], repos[j]) < 0.01)
                {
                    ito = j;
                    break;
                }
            }
            if (ito < 0)
            {
                indexmap[i] = repos.Count;
                repos.Add(navtri.vertices[i]);
            }
            else
            {
                indexmap[i] = ito;
            }
        }

        //关系是 index 公用的三角形表示他们共同组成多边形
        //多边形之间的连接用顶点位置识别
        List <int>   polylast = new List <int>();
        List <int[]> polys    = new List <int[]>();

        for (int i = 0; i < navtri.indices.Length / 3; i++)
        {
            int i0 = navtri.indices[i * 3 + 0];
            int i1 = navtri.indices[i * 3 + 1];
            int i2 = navtri.indices[i * 3 + 2];

            if (polylast.Contains(i0) || polylast.Contains(i1) || polylast.Contains(i2))
            {
                if (polylast.Contains(i0) == false)
                {
                    polylast.Add(i0);
                }
                if (polylast.Contains(i1) == false)
                {
                    polylast.Add(i1);
                }
                if (polylast.Contains(i2) == false)
                {
                    polylast.Add(i2);
                }
            }
            else
            {
                if (polylast.Count > 0)
                {
                    polys.Add(polylast.ToArray());
                }
                polylast.Clear();
                polylast.Add(i0);
                polylast.Add(i1);
                polylast.Add(i2);
            }
        }
        if (polylast.Count > 0)
        {
            polys.Add(polylast.ToArray());
        }

        string outnav = "";

        outnav = "{\"v\":[\n";
        for (int i = 0; i < repos.Count; i++)
        {
            if (i > 0)
            {
                outnav += ",\n";
            }

            outnav += "[" + (int)(repos[i].x * 10000) + "," + (int)(repos[i].z * 10000) + "]";
        }
        outnav += "\n],\"p\":[\n";

        for (int i = 0; i < polys.Count; i++)
        {
            string outs = indexmap[polys[i][0]].ToString();
            for (int j = 1; j < polys[i].Length; j++)
            {
                outs += "," + indexmap[polys[i][j]];
            }

            if (i > 0)
            {
                outnav += ",\n";
            }

            outnav += "[" + outs + "]";
        }
        outnav += "\n]}";

        System.IO.File.WriteAllText(outfile, outnav);
    }
Example #28
0
 private static extern void CalculateTriangulation_Injected(out NavMeshTriangulation ret);
    void PlaceProbes()
    {
        GameObject probe = probeObject;

        if (probe != null)
        {
            LightProbeGroup p = probe.GetComponent <LightProbeGroup>();

            if (p != null)
            {
                working = true;

                progress = 0.0f;
                current  = "Triangulating navmesh...";
                EditorUtility.DisplayProgressBar("Generating probes", current, progress);


                probe.transform.position = Vector3.zero;

                UnityEngine.AI.NavMeshTriangulation navMesh = UnityEngine.AI.NavMesh.CalculateTriangulation();


                current = "Generating necessary lists...";
                EditorUtility.DisplayProgressBar("Generating probes", current, progress);

                Vector3[]            newProbes = navMesh.vertices;
                List <Vector3>       probeList = new List <Vector3>(newProbes);
                List <ProbeGenPoint> probeGen  = new List <ProbeGenPoint>();

                foreach (Vector3 pg in probeList)
                {
                    probeGen.Add(new ProbeGenPoint(pg, false));
                }

                EditorUtility.DisplayProgressBar("Generating probes", current, progress);

                List <Vector3> mergedProbes = new List <Vector3>();

                int probeListLength = newProbes.Length;

                int done = 0;
                foreach (ProbeGenPoint pro in probeGen)
                {
                    if (pro.used == false)
                    {
                        current  = "Checking point at " + pro.point.ToString();
                        progress = (float)done / (float)probeListLength;
                        EditorUtility.DisplayProgressBar("Generating probes", current, progress);
                        List <Vector3> nearbyProbes = new List <Vector3>();
                        nearbyProbes.Add(pro.point);
                        pro.used = true;
                        foreach (ProbeGenPoint pp in probeGen)
                        {
                            if (pp.used == false)
                            {
                                current = "Checking point at " + pro.point.ToString();
                                //EditorUtility.DisplayProgressBar ("Generating probes", current, progress);
                                if (Vector3.Distance(pp.point, pro.point) <= mergeDistance)
                                {
                                    pp.used = true;
                                    nearbyProbes.Add(pp.point);
                                }
                            }
                        }

                        Vector3 newProbe = new Vector3();
                        foreach (Vector3 prooo in nearbyProbes)
                        {
                            newProbe += prooo;
                        }
                        newProbe /= nearbyProbes.ToArray().Length;
                        newProbe += Vector3.up;

                        mergedProbes.Add(newProbe);
                        done += 1;
                        //Debug.Log ("Added probe at point " + newProbe.ToString ());
                    }
                }

                /*for(int i=0; i<newProbes.Length; i++) {
                 *      newProbes[i] = newProbes[i] + Vector3.up;
                 * }*/


                current = "Final steps...";
                EditorUtility.DisplayProgressBar("Generating probes", current, progress);

                p.probePositions = mergedProbes.ToArray();
                EditorUtility.DisplayProgressBar("Generating probes", current, progress);

                working = false;
            }
            else
            {
                EditorUtility.DisplayDialog("Error", "Probe object does not have a Light Probe Group attached to it", "OK");
            }
        }
        else
        {
            EditorUtility.DisplayDialog("Error", "Probe object not set", "OK");
        }
    }
Example #30
0
    static void Export()
    {
        Debug.Log("ExportNavMesh");

        UnityEngine.AI.NavMeshTriangulation tmpNavMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();

        //新建文件
        string tmpPath = Application.dataPath + "/" + SceneManager.GetActiveScene().name + ".lua";

        Debug.Log("=====================" + tmpPath + tmpNavMeshTriangulation.vertices.Length);
        StreamWriter tmpStreamWriter = new StreamWriter(tmpPath);

        tmpStreamWriter.WriteLine("-------本文件是地图导航网格文本");
        tmpStreamWriter.WriteLine("local nav_triangle = {");

        Hashtable pointTable = new Hashtable();

        //顶点
        for (int i = 0; i < tmpNavMeshTriangulation.vertices.Length; i++)
        {
            //tmpStreamWriter.WriteLine("v  " + tmpNavMeshTriangulation.vertices[i].x + " " + tmpNavMeshTriangulation.vertices[i].y + " " + tmpNavMeshTriangulation.vertices[i].z);
            if (!pointTable.ContainsKey(tmpNavMeshTriangulation.vertices[i]))
            {
                pointTable.Add(tmpNavMeshTriangulation.vertices[i], new ArrayList());
            }

            (pointTable[tmpNavMeshTriangulation.vertices[i]] as ArrayList).Add(i);
        }

        //tmpStreamWriter.WriteLine("g pPlane1");

        Hashtable          lineTable = new Hashtable();
        List <NavTriangle> triangles = new List <NavTriangle>();

        int triangleIndex = 1;

        for (int i = 0; i < tmpNavMeshTriangulation.indices.Length;)
        {
            //tmpStreamWriter.WriteLine("f " + (tmpNavMeshTriangulation.indices[i] + 1) + " " + (tmpNavMeshTriangulation.indices[i + 1] + 1) + " " + (tmpNavMeshTriangulation.indices[i + 2] + 1));
            NavTriangle item = new NavTriangle();
            item.tLineKeyArr = new string[3];
            item.tIndex      = triangleIndex;
            SetTriangleInfo(0, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 2]]
                            , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 1]]
                            , pointTable, item, lineTable);
            SetTriangleInfo(1, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 1]]
                            , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i]]
                            , pointTable, item, lineTable);
            SetTriangleInfo(2, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 2]]
                            , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i]]
                            , pointTable, item, lineTable);

            triangles.Add(item);
            triangleIndex += 1;
            i              = i + 3;
        }

        for (int i = 0; i < triangles.Count; i++)
        {
            tmpStreamWriter.WriteLine(string.Format("\t[{0}] = {{", triangles[i].tIndex));

            tmpStreamWriter.WriteLine(string.Format("\t\tv = {{{{{0}, {1}, {2}}}, {{{3}, {4}, {5}}},{{{6}, {7}, {8}}}}},"
                                                    , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 2]].x, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 2]].z, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 2]].y
                                                    , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 1]].x, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 1]].z, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 1]].y
                                                    , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3]].x, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3]].z, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3]].y));

            tmpStreamWriter.WriteLine(string.Format("\t\tnedge = {{{0}, {1}, {2}}},"
                                                    , GetSameLine(triangles[i].tLineKeyArr[0], triangles[i].tIndex, lineTable)
                                                    , GetSameLine(triangles[i].tLineKeyArr[1], triangles[i].tIndex, lineTable)
                                                    , GetSameLine(triangles[i].tLineKeyArr[2], triangles[i].tIndex, lineTable)));

            tmpStreamWriter.WriteLine("\t},\n");
        }

        tmpStreamWriter.WriteLine("}");

        tmpStreamWriter.Flush();
        tmpStreamWriter.Close();

        Debug.Log("ExportNavMesh Success");
    }