/// <summary> /// Creates a tile vertex /// </summary> /// <param name="pos">The position of the tile</param> /// <param name="x">The x position of this tile</param> /// <param name="y">The y position of this tile.</param> /// <param name="v">Which corner of the tile is this vertex?</param> /// <param name="w">The height level of this vertex</param> /// <returns>The created vertex</returns> public VertexMultitextured MakeVertex(Vector3 pos, int x, int y, int v, int w) { // Transform the v into an xy coordinate // 0 2 = v // 1 3 int xcorner = (v < 2 ? -1 : 1); int ycorner = (v < 2 ? v * 2 - 1 : (v - 2) * 2 - 1); VertexMultitextured vertex = new VertexMultitextured(); vertex.Position = pos; vertex.Texture = new Vector2(x + xcorner / 2f, y + ycorner / 2f) * 0.03f; int here = Tiles[x, y].CliffLevel; if (w != -1) { vertex.Cliff = new Vector2(x, y + w) * 0.03f; } else { vertex.Cliff = new Vector2(-1f); } // TODO: Get a real normal for it vertex.Normal = Vector3.One; return(vertex); }
/// <summary> /// Construye los vértices a partir del mapa de alturas especificado /// </summary> /// <param name="cellSize">Tamaño de la celda</param> /// <param name="pLevel1">Proporción de textura del nivel 1</param> /// <param name="pLevel1">Proporción de textura del nivel 2</param> /// <param name="pLevel1">Proporción de textura del nivel 3</param> /// <returns>Devuelve la colección de vértices</returns> public VertexMultitextured[] BuildVertices(float cellSize, float pLevel1, float pLevel2, float pLevel3) { // Contador de vértices int vertexCountX = this.Width; int vertexCountZ = this.Deep; int vertexCount = vertexCountX * vertexCountZ; float level0 = this.Min; float level1 = this.Max * pLevel1; float level2 = this.Max * pLevel2; float level3 = this.Max * pLevel3; float level4 = this.Max; // Crear los vértices List <VertexMultitextured> vertList = new List <VertexMultitextured>(vertexCount); Vector3[,] normals = this.CreateNormals(cellSize); for (int width = 0; width < vertexCountX; width++) { for (int deep = 0; deep < vertexCountZ; deep++) { VertexMultitextured newVertex = new VertexMultitextured(); float posX = width * cellSize; float posY = this.m_Data[deep, width]; float posZ = deep * cellSize; newVertex.Position = new Vector3(posX, posY, posZ); newVertex.Normal = normals[deep, width]; newVertex.TextureCoordinate.X = (float)width / 10.0f; newVertex.TextureCoordinate.Y = (float)deep / 10.0f; float twX = (posY < level1) ? (posY / level1) : 0.0f; float twY = (posY < level2) ? (posY / level2) : 0.0f; float twZ = (posY < level3) ? (posY / level3) : 0.0f; float twW = (posY < level4) ? (posY / level4) : 0.0f; float totalWeight = twX + twY + twZ + twW; newVertex.TexWeights.X = twX / totalWeight; newVertex.TexWeights.Y = twY / totalWeight; newVertex.TexWeights.Z = twZ / totalWeight; newVertex.TexWeights.W = twW / totalWeight; vertList.Add(newVertex); } } return(vertList.ToArray()); }
public static void generateRegionMapLOD2(out VertexMultitextured[] vertices, out int[] sectors, out ResourceCell[] resources, int width, int height, int minAltitude, int maxAltitude) { Random rand = new Random(); int _vertexCount = width * height; //Initialize our array to hold the vertices vertices = new VertexMultitextured[_vertexCount]; sectors = new int[_vertexCount]; // CreateWaterBorder(map, width, height); // CreateBeachBorder(map, width, height); float regionFraction = 0.0005f; //0.001f; // what fraction of the points are given a random height int RegionCenterPointCount = (int)Math.Floor(width * height * regionFraction); int[] pointX = new int[RegionCenterPointCount]; int[] pointY = new int[RegionCenterPointCount]; int[] pointAltitude = new int[RegionCenterPointCount]; float[,] CenterPointTexureWeights = new float[RegionCenterPointCount, 4]; // give those points an altitude and a texture. for (int i = 0; i < RegionCenterPointCount; i++) { pointX[i] = rand.Next(width); pointY[i] = rand.Next(height); pointAltitude[i] = rand.Next(minAltitude, maxAltitude - 1) + 1; float sum = 0; for (int t = 0; t < 4; t++) { CenterPointTexureWeights[i, t] = rand.Next(1, 100); sum += CenterPointTexureWeights[i, t]; } for (int t = 0; t < 4; t++) { CenterPointTexureWeights[i, t] = CenterPointTexureWeights[i, t] / sum; } } // find for each point on the map, the closest Region Center Point int closestRegionPoint = 0; int closestTexture = 0; double SmallestDistance = double.MaxValue; double distance; for (int y = 0; y < height - 0; y = y + 1) { for (int x = 0; x < width - 0; x = x + 1) { // find the closest region center point for (int r = 0; r < RegionCenterPointCount; r++) { distance = DistanceSquared(x, y, pointX[r], pointY[r]); if (distance < SmallestDistance) { SmallestDistance = distance; closestRegionPoint = r; } } double pointDistanceToRegionPoint = SmallestDistance; // find region point in line with our point to extrapolate the texture weights SmallestDistance = double.MaxValue; for (int r = 0; r < RegionCenterPointCount; r++) { if ((pointX[r] <= pointX[closestRegionPoint] && x <= pointX[closestRegionPoint]) || (pointX[r] > pointX[closestRegionPoint] && x > pointX[closestRegionPoint])) { if ((pointY[r] <= pointY[closestRegionPoint] && y <= pointY[closestRegionPoint]) || (pointY[r] > pointY[closestRegionPoint] && y > pointY[closestRegionPoint])) { // point lays in the same quadrant (relative to our regioncenter point) as our current point distance = DistanceSquared(pointX[closestRegionPoint], pointY[closestRegionPoint], pointX[r], pointY[r]); if (distance < SmallestDistance) { SmallestDistance = distance; closestTexture = r; } } } } // interpolate between the found points double dif; float[] texuresWeights = new float[4]; for (int i = 0; i < 4; i++) { dif = CenterPointTexureWeights[closestRegionPoint, i] - CenterPointTexureWeights[closestTexture, i]; texuresWeights[i] = (float)(CenterPointTexureWeights[closestRegionPoint, i] + dif / (pointDistanceToRegionPoint)); if (pointDistanceToRegionPoint < 0.00001f) { texuresWeights[i] = CenterPointTexureWeights[closestRegionPoint, i]; } } float mapCellScaleDivTextureSize = (float)LODTerrain.LODTerrain.mapCellScale / (float)LODTerrain.LODTerrain.textureSize; int adress = getCellAdress(x, y, width); vertices[adress] = new VertexMultitextured(); vertices[adress].Position = new Vector3(x * LODTerrain.LODTerrain.mapCellScale, pointAltitude[closestRegionPoint] * LODTerrain.LODTerrain.mapHeightScale, y * LODTerrain.LODTerrain.mapCellScale); vertices[adress].TextureCoordinate.X = ((float)(x * mapCellScaleDivTextureSize)); vertices[adress].TextureCoordinate.Y = ((float)(y * mapCellScaleDivTextureSize)); vertices[adress].TexWeights = new Vector4(texuresWeights[0], texuresWeights[1], texuresWeights[2], texuresWeights[3]); vertices[adress].Normal = new Vector3(0, 0, 0); sectors[adress] = closestRegionPoint; SmallestDistance = double.MaxValue; } } // Filter(vertices, width, height, minAltitude, maxAltitude); resources = GenerateResources(RegionCenterPointCount); }
/*private void GenerateTreePositions(VertexMultitextured[] terrainVertices) { treeList = new List<Vector3>(); treeList.Add(terrainVertices[3310].Position); treeList.Add(terrainVertices[3315].Position); treeList.Add(terrainVertices[3320].Position); treeList.Add(terrainVertices[3325].Position); }*/ private void GenerateTreePositions(VertexMultitextured[] terrainVertices) { Color[] treeMapColors = new Color[treeMap.Width * treeMap.Height]; treeMap.GetData(treeMapColors); int[,] noiseData = new int[treeMap.Width, treeMap.Height]; for (int x = 0; x < treeMap.Width; x++) for (int y = 0; y < treeMap.Height; y++) noiseData[x, y] = treeMapColors[y + x * treeMap.Height].R; treeList = new List<Vector3>(); Random random = new Random(); for (int x = 0; x < terrainWidth; x++) { for (int y = 0; y < terrainLength; y++) { float terrainHeight = heightData[x, y]; if ((terrainHeight > TREE_MIN_HT) && (terrainHeight < TREE_MAX_HT)) { float flatness = Vector3.Dot(terrainVertices[x + y * terrainWidth].Normal, new Vector3(0, 1, 0)); float minFlatness = (float)Math.Cos(MathHelper.ToRadians(TREE_MAX_SLOPE)); if (flatness > minFlatness) { float relx = (float)x / (float)terrainWidth; float rely = (float)y / (float)terrainLength; float noiseValueAtCurrentPosition = noiseData[(int)(relx * treeMap.Width), (int)(rely * treeMap.Height)]; float treeDensity; if (noiseValueAtCurrentPosition > TREEMAP_HI_THOLD) treeDensity = HI_NUM_TREES; else if (noiseValueAtCurrentPosition > TREEMAP_MED_THOLD) treeDensity = MED_NUM_TREES; else if (noiseValueAtCurrentPosition > TREEMAP_LOW_THOLD) treeDensity = LOW_NUM_TREES; else treeDensity = 0; for (int currDetail = 0; currDetail < treeDensity; currDetail++) { float rand1 = (float)random.Next(1000) / 1000.0f; float rand2 = (float)random.Next(1000) / 1000.0f; Vector3 treePos = new Vector3((float)x - rand1, 0, -(float)y - rand2); treePos.Y = heightData[x, y]; treeList.Add(treePos); } } } } } }