计算格子贴图索引数字
为噪声图生成的随机数值匹配对应的地形
public enum MapVertexType
{
Frost,
Marsh,
}
public class MapVertex
{
public Vector3 Position;
public MapVertexType VertexType;
}
public class MapCell
{
public Vector3 Position;
public int TextureIndex;
}
定义地图类型枚举变量并让顶点持有,为地图格子添加贴图索引成员。
/// <summary>
/// 计算格子贴图的索引数字
/// </summary>
public int[,] CalculateCellTextureIndex(float [,] noiseMap, float limit)
{
int width = noiseMap.GetLength(0);
int height = noiseMap.GetLength(1);
for (int x = 1; x <= width; x++)
{
for (int z = 1; z <= height; z++)
{
//基于噪声的值确定定点类型
//大于边界是沼泽,否则是森林
if (noiseMap[x - 1,z - 1] >= limit)
{
SetVertexType(x, z, MapVertexType.Marsh);
}
else
{
SetVertexType(x,z, MapVertexType.Forest);
}
}
}
int [,] textureIndexMap = new int[width,height];
for (int x = 0; x < width; x++)
{
for (int z = 0; z < height; z++)
{
textureIndexMap[x, z] = GetCell(x + 1, z + 1).TextureIndex;
}
}
return textureIndexMap;
}
}
注意:
-
顶点索引的范围在[1,map.width]和[1,map.height],而格子在[0,map.width]和[0,map.height]。
-
噪声图索引区间长度和顶点一致是n-1,但噪声图索引范围是[0,map.weight/height - 2],顶点是[1,map.weight/height - 1],所以从根据顶点索引从噪声图中取数据应该-1,即noiseMap[x - 1,z - 1]。
完善边界
将获取格子的逻辑都修改成使用上节优化后的GetCell方法。
/// <summary>
/// 获取左下角格子
/// </summary>
public MapCell GetLeftBottomMapCell(Vector2Int vertexIndex)
{
return GetCell(vertexIndex);
// return cellDic[vertexIndex];
}
/// <summary>
/// 获取右下角格子
/// </summary>
public MapCell GetRightBottomMapCell(Vector2Int vertexIndex)
{
return GetCell(vertexIndex.x + 1, vertexIndex.y);
//return cellDic[new Vector2Int(vertexIndex.x + 1,vertexIndex.y)];
}
/// <summary>
/// 获取左上角格子
/// </summary>
public MapCell GetLeftTopMapCell(Vector2Int vertexIndex)
{
//return cellDic[new Vector2Int(vertexIndex.x, vertexIndex.y + 1)];
return GetCell(vertexIndex.x, vertexIndex.y + 1);
}
/// <summary>
/// 获取右上角格子
/// </summary>
public MapCell GetRightTopMapCell(Vector2Int vertexIndex)
{
//return cellDic[new Vector2Int(vertexIndex.x + 1, vertexIndex.y + 1)];
return GetCell(vertexIndex.x + 1, vertexIndex.y + 1);
}
修改顶点周围的贴图索引
private void SetVertexType(Vector2Int vertexIndex, MapVertexType mapVertexType)
{
MapVertex vertex = GetVertex(vertexIndex);
if (vertex.VertexType != mapVertexType)
{
vertex.VertexType = mapVertexType;
//只有沼泽需要计算
if (vertex.VertexType == MapVertexType.Marsh)
{
// 计算附近的贴图权重
MapCell tempCell = GetLeftBottomMapCell(vertexIndex);
if (tempCell != null) tempCell.TextureIndex += 1;
tempCell = GetRightBottomMapCell(vertexIndex);
if (tempCell != null) tempCell.TextureIndex += 2;
tempCell = GetLeftTopMapCell(vertexIndex);
if (tempCell != null) tempCell.TextureIndex += 4;
tempCell = GetRightTopMapCell(vertexIndex);
if (tempCell != null) tempCell.TextureIndex += 8;
}
}
}
只有沼泽存在地形叠加,森林中的每个树独立不需要叠加,四个角的贴图设置成1,2,4,8的原因见地形拼接算法理论,本质是1,2,4,8可以组合生成1-15,覆盖了3*3地形叠加的所有可能情况。
输出每个格子贴图索引
//确认顶点的类型、计算顶点周围的贴图索引数字
int[,] celltexutreIndexMap = grid.CalculateCellTextureIndex(noiseMap, limit);
包含每个格子贴图的索引,对应着沼泽贴图不同的叠加形态。