private void Test( ) { Vector2 A = new Vector2(4, 3); Vector2 B = new Vector2(22, 3); Vector2 C = new Vector2(25, 30); Vector2 D = new Vector2(5, 28); Vector2 E = new Vector2(55, 2); Vector2 F = new Vector2(50, 32); float a = Random.value; float b = Random.value; float c = Random.value; float d = Random.value; float e = Random.value; float f = Random.value; print(a + " " + b + " " + c + " " + d); print(RMGUtility.LerpSquare(A, a, B, b, C, c, D, d, B.x, B.y)); print(b + " " + e + " " + f + " " + c); float[,] heights = new float[65, 65]; for (int i = 0; i < 65; i++) { for (int j = 0; j < 65; j++) { if (RMGUtility.PointInSquare(A, B, C, D, j, i)) { heights[i, j] = RMGUtility.LerpSquare(A, a, B, b, C, c, D, d, j, i); } if (RMGUtility.PointInSquare(B, E, F, C, j, i)) { heights[i, j] = RMGUtility.LerpSquare(B, b, E, e, F, f, C, c, j, i); } } } TerrainData trdata = new TerrainData(); trdata.heightmapResolution = 65; trdata.size = new Vector3(100, 20, 100); trdata.SetHeights(0, 0, heights); GameObject tr = Terrain.CreateTerrainGameObject(trdata); }
/// <summary> /// 设置高度图 /// </summary> /// <param name="terrainData">地形数据</param> private void _SetHeight(TerrainData terrainData, float maxHeight) { int hmr = terrainData.heightmapResolution; float[,] heights = new float[hmr, hmr]; // 每栅格采样点数 byte sample = (byte)((hmr - 1) / m); float pixelSize = _squareSize / sample; for (uint i = 0; i < hmr; i++) { for (uint j = 0; j < hmr; j++) { // 边界 if (i < sample || j < sample || i >= hmr - 1 - sample || j >= hmr - 1 - sample) { heights[i, j] = 0; continue; } // 落到中心及周围8个栅格中的某一个,x、y是栅格的序号 uint x = j / sample; uint y = i / sample; // 坐标 = 序号 * 像素大小 float xPoint = (float)j * pixelSize; float yPoint = (float)i * pixelSize; // 落到哪里就用哪个的四个拐角插值 // 先判断是否在中间的栅格 if (RMGUtility.PointInSquare( _raster.SquareCorners[x, y], _raster.SquareCorners[x + 1, y], _raster.SquareCorners[x + 1, y + 1], _raster.SquareCorners[x, y + 1], xPoint, yPoint)) { if (_centerTypes[x, y] == CenterType.kLand) { heights[i, j] = _Lerp4Height(x, y, xPoint, yPoint) / maxHeight; } } else { // 不在中间 // 退到左上角 x--; y--; for (byte p = 0; p < 3; p++) { for (byte q = 0; q < 3; q++) { // 中间的不用测试 if (p == 1 && q == 1) { continue; } uint xx = x + p; uint yy = y + q; // 判断是否在四边形内 if (RMGUtility.PointInSquare( _raster.SquareCorners[xx, yy], _raster.SquareCorners[xx + 1, yy], _raster.SquareCorners[xx + 1, yy + 1], _raster.SquareCorners[xx, yy + 1], xPoint, yPoint)) { if (_centerTypes[xx, yy] == CenterType.kOcean) { heights[i, j] = 0; } else { heights[i, j] = _Lerp4Height(xx, yy, xPoint, yPoint) / maxHeight; } continue; } } } } } } terrain.terrainData.SetHeightsDelayLOD(0, 0, heights); }