Esempio n. 1
0
        private static void callNative(NavMeshConfig config, SceneRecastData data, int currentMapID)
        {
            BytesWriteStream stream = new BytesWriteStream();

            stream.setUseBitBoolean(false);

            config.write(stream);

            string cStr   = ShineToolGlobal.mapInfoPath + "/navConfig.bin";
            string dStr   = SceneEditorWindow.getMapFilePathFront(currentMapID) + "_navData.bin";
            string objStr = SceneEditorWindow.getMapFilePathFront(currentMapID) + "_navData.obj";

            FileUtils.writeFileForBytesWriteStream(cStr, stream);

            stream.clear();
            data.write(stream);
            FileUtils.writeFileForBytesWriteStream(dStr, stream);

            if (_needObjFile)
            {
                StringBuilder sb = new StringBuilder();

                foreach (Vector3 vec in data.vertices)
                {
                    sb.Append('v');
                    sb.Append(' ');
                    sb.Append(vec.x);
                    sb.Append(' ');
                    sb.Append(vec.y);
                    sb.Append(' ');
                    sb.Append(vec.z);
                    sb.Append('\n');
                }

                int[] navIndices = data.triangles.getValues();
                int   len        = data.triangles.size() / 3;

                for (int i = 0; i < len; i++)
                {
                    sb.Append('f');
                    sb.Append(' ');
                    sb.Append(navIndices[i * 3] + 1);
                    sb.Append(' ');
                    sb.Append(navIndices[i * 3 + 1] + 1);
                    sb.Append(' ');
                    sb.Append(navIndices[i * 3 + 2] + 1);
                    sb.Append('\n');
                }

                FileUtils.writeFileForUTF(objStr, sb.ToString());
            }

            Ctrl.print("callJar");
            ToolFileUtils.executeServerTool("exportNav", currentMapID.ToString());
            Ctrl.print("OK");
        }
Esempio n. 2
0
        /** 将当前场景的mesh写出到路径 */
        public static void writeMesh(int currentMapID)
        {
            _needObjFile = CommonSetting.serverMapRecastNeedObjFile;

            MeshFilter[] mfs = Object.FindObjectsOfType <MeshFilter>();

            Terrain[] terrains = Object.FindObjectsOfType <Terrain>();

            if (terrains.Length > 1)
            {
                Ctrl.errorLog("地形数目非法");
                return;
            }

            NavMeshConfig   config = new NavMeshConfig();
            SceneRecastData data   = new SceneRecastData();

            Terrain terrain = terrains.Length > 0 ? terrains[0] : null;

            Bounds b = new Bounds();

            _newBound = true;

            if (terrain != null)
            {
                TerrainData terrainData   = terrain.terrainData;
                Bounds      terrainBounds = terrainData.bounds;
                terrainBounds.center = terrain.transform.TransformPoint(terrainBounds.center);

//				Bounds tBounds=new Bounds(new Vector3(terrainBounds.center.x, 0.0f, terrainBounds.center.z), new Vector3(ChunkSize, 1048576.0f, ChunkSize));
//
//				int sx = (int)Mathf.Floor(tBounds.center.x / ChunkSize);
//				int sz = (int) Mathf.Floor(tBounds.center.z / ChunkSize);
//
//				var tilesPerChunks = (int)(ChunkSize / (config.tileSize * config.cellSize));
//
//				data.sizeX = tilesPerChunks;
//				data.sizeZ = tilesPerChunks;
//				data.originX = sx * tilesPerChunks;
//				data.originZ = sz * tilesPerChunks;
//				data.tileSize = config.tileSize * config.cellSize;

                if (_newBound)
                {
                    _newBound = false;
                    b         = terrainBounds;
                }
                else
                {
                    b.Encapsulate(terrainBounds);
                }

                SceneRecastTerrainData tData = data.terrain = new SceneRecastTerrainData();
                tData.origin = terrainBounds.min;
                int     rx       = tData.resolutionX = terrainData.heightmapResolution;
                int     rz       = tData.resolutionZ = terrainData.heightmapResolution;
                Vector3 mapScale = terrainData.heightmapScale;

                tData.unit    = mapScale;
                tData.unit.y /= 32768.0f;

                int startSize = data.triangles.size();
                //terrain

                short[] heightSamples = tData.heightSamples = new short[tData.resolutionX * tData.resolutionZ];
                float[,] rawHeights = terrainData.GetHeights(0, 0, terrainData.heightmapResolution, terrainData.heightmapResolution);

                int zm = rz - 1;
                int xm = rx - 1;

                for (int j = 0; j < rz; j++)
                {
                    for (int i = 0; i < rx; i++)
                    {
                        float rawHeight = rawHeights[j, i];

                        if (_needObjFile)
                        {
                            data.vertices.add(new Vector3(i * mapScale.x, rawHeight * mapScale.y, j * mapScale.z));
                        }

                        short sample = (short)(rawHeight * 32768.0f);
                        if (sample < 0)
                        {
                            sample = 32767;
                        }

                        heightSamples[i + (j * rx)] = sample;

                        if (_needObjFile)
                        {
                            if (j < zm && i < xm)
                            {
                                data.triangles.add(i + (j * rx));
                                data.triangles.add(i + ((j + 1) * rx));
                                data.triangles.add((i + 1) + ((j + 1) * rx));

                                data.triangles.add((i + 1) + ((j + 1) * rx));
                                data.triangles.add((i + 1) + (j * rx));
                                data.triangles.add(i + (j * rx));
                            }
                        }
                    }
                }

                if (_needObjFile)
                {
                    if ((data.triangles.size() - startSize) != zm * xm * 6)
                    {
                        Ctrl.print("不对1");
                    }
                }

                //trees
                foreach (TreeInstance tree in terrainData.treeInstances)
                {
                    GameObject treeObj = (GameObject)PrefabUtility.InstantiatePrefab(terrainData.treePrototypes[tree.prototypeIndex].prefab);
                    treeObj.transform.position   = Vector3.Scale(tree.position, terrainData.size) + terrain.transform.position;
                    treeObj.transform.localScale = new Vector3(tree.widthScale, tree.heightScale, tree.widthScale);
                    treeObj.transform.rotation   = Quaternion.AngleAxis(tree.rotation * Mathf.Rad2Deg, Vector3.up);

                    MeshFilter[] treeMeshFilters = treeObj.GetComponentsInChildren <MeshFilter>();

                    foreach (MeshFilter meshFilter in treeMeshFilters)
                    {
                        doOneMesh(data, meshFilter, ref b);
                    }
                }
            }

            //meshes
            foreach (MeshFilter meshFilter in mfs)
            {
                doOneMesh(data, meshFilter, ref b);
            }

            int gx = (int)(b.size.x / config.cellSize + 0.5f);
            int gz = (int)(b.size.z / config.cellSize + 0.5f);
            int tz = (int)config.tileSize;

            data.sizeX = (gx + tz - 1) / tz;
            data.sizeZ = (gz + tz - 1) / tz;

//				data.sizeX = (int)(b.size.x / (config.tileSize * config.cellSize));
//				data.sizeZ = (int)(b.size.z / (config.tileSize * config.cellSize));

            int sx = (int)Mathf.Floor(b.min.x / data.sizeX);
            int sz = (int)Mathf.Floor(b.min.z / data.sizeZ);

            data.originX  = sx * data.sizeX;
            data.originZ  = sz * data.sizeZ;
            data.tileSize = config.tileSize * config.cellSize;

            data.min    = b.min;
            data.min.y -= 1;
            data.max    = b.max;
            data.max.y += 1;

            callNative(config, data, currentMapID);
        }