/// <summary> /// Calculate the vertices for a single patch in the tile /// </summary> /// <param name="tile">The tile (parsed .t-file)</param> /// <param name="patch">The terrain patch (one of the patches in the tile)</param> /// <returns>The texture name</returns> private string CreateVerticesFromPatch(Tile tile, terrain_patchset_patch patch) { var ts = tile.Shaders[patch.ShaderIndex].terrain_texslots; string textureName = ts[0].Filename; if (!textureManager.TextureIsLoaded(textureName)) { // apparently the texture was not found earlier on, so no use bothering about vertices return(textureName); } if (!newVertices.ContainsKey(textureName)) { // in case this is the first time we use this particular texture newVertices.Add(textureName, new List <VertexPositionTexture>()); } // 1 square or quad is two triangles CreateSingleCornerVertex(tile, patch, 0, 0, textureName); CreateSingleCornerVertex(tile, patch, 1, 0, textureName); CreateSingleCornerVertex(tile, patch, 0, 1, textureName); CreateSingleCornerVertex(tile, patch, 0, 1, textureName); CreateSingleCornerVertex(tile, patch, 1, 0, textureName); CreateSingleCornerVertex(tile, patch, 1, 1, textureName); return(textureName); }
public TerrainPrimitive(Viewer viewer, TileManager tileManager, Tile tile, int x, int z) { Viewer = viewer; TileX = tile.TileX; TileZ = tile.TileZ; Size = tile.Size; PatchX = x; PatchZ = z; PatchSize = tile.Size * 2048 / tile.PatchCount; TileManager = tileManager; Tile = tile; Patch = Tile.GetPatch(x, z); var cx = Patch.CenterX - 1024; var cz = Patch.CenterZ - 1024 + 2048 * tile.Size; PatchLocation = new Vector3(cx, Tile.Floor, cz); PatchVertexBuffer = GetVertexBuffer(out AverageElevation); PatchIndexBuffer = GetIndexBuffer(out PatchPrimitiveCount); var terrainMaterial = tile.Size > 2 ? "TerrainSharedDistantMountain" : PatchIndexBuffer == null ? "TerrainShared" : "Terrain"; var ts = Tile.Shaders[Patch.ShaderIndex].terrain_texslots; var uv = Tile.Shaders[Patch.ShaderIndex].terrain_uvcalcs; if (ts.Length > 1) { PatchMaterial = viewer.MaterialManager.Load(terrainMaterial, Helpers.GetTerrainTextureFile(viewer.Simulator, ts[0].Filename) + "\0" + Helpers.GetTerrainTextureFile(viewer.Simulator, ts[1].Filename) + (uv[1].D != 0 && uv[1].D != 32 ? "\0" + uv[1].D.ToString(): "")); } else { PatchMaterial = viewer.MaterialManager.Load(terrainMaterial, Helpers.GetTerrainTextureFile(viewer.Simulator, ts[0].Filename) + "\0" + Helpers.GetTerrainTextureFile(viewer.Simulator, "microtex.ace")); } if (SharedPatchIndexBuffer == null) { SetupSharedData(Viewer.GraphicsDevice); } Tile = null; Patch = null; DummyVertexBuffer = new VertexBuffer(viewer.GraphicsDevice, DummyVertexDeclaration, 1, BufferUsage.WriteOnly); DummyVertexBuffer.SetData(DummyVertexData); VertexBufferBindings = new[] { new VertexBufferBinding(PatchVertexBuffer), new VertexBufferBinding(DummyVertexBuffer) }; }
/// <summary> /// Create a single vertex for a corner in the patch /// </summary> /// <param name="tile">The tile (parsed .t-file)</param> /// <param name="patch">The terrain patch (one of the patches in the tile)</param> /// <param name="cornerIndexX">Defines the x-value of the corner (0 or 1)</param> /// <param name="cornerIndexZ">Defines the z-value of the corner (0 or 1)</param> /// <param name="textureName">The name of the texture</param> private void CreateSingleCornerVertex(Tile tile, terrain_patchset_patch patch, float cornerIndexX, float cornerIndexZ, string textureName) { int squaresPerPatch = 16; cornerIndexX *= squaresPerPatch; cornerIndexZ *= squaresPerPatch; var step = tile.SampleSize; float cornerX = patch.CenterX - 1024; float cornerZ = patch.CenterZ - 1024 + 2048 * tile.Size; cornerX += -patch.RadiusM + cornerIndexX * step; cornerZ += -patch.RadiusM + (squaresPerPatch - cornerIndexZ) * step; var location = new WorldLocation(tile.TileX, tile.TileZ, cornerX, 0, cornerZ); // Rotate, Flip, and stretch the texture using the matrix coordinates stored in terrain_patchset_patch // transform uv by the 2x3 matrix made up of X,Y W,B C,H var U = cornerIndexX * patch.W + cornerIndexZ * patch.B + patch.X; var V = cornerIndexX * patch.C + cornerIndexZ * patch.H + patch.Y; newVertices[textureName].Add(new VertexPositionTexture(locationTranslator.VertexPosition(location), new Vector2(U, V))); }