public static void LoadRawFileAsTexture(string rawFile, Texture2D output, HeightfileFormat format) { if (!File.Exists(rawFile)) { throw new FileNotFoundException("Raw file does not exist: " + rawFile); } // Open filestream and read into bytebuffer byte[] bytes = File.ReadAllBytes(rawFile); int resolution = GetHeightmapResolution(bytes, format); ValidateHeightmapRaw(bytes, output.width, format); //Texture2D tex = new Texture2D(resolution, resolution, TextureFormat.ARGB32, true); // Prepare colorbuffer Color[] pixels = new Color[resolution * resolution]; // Parse bytebuffer into colors, taking care of mirroring and byte format int i = 0; int j = 0; for (int x = 0; x < resolution; x++) { for (int y = 0; y < resolution; y++) { float gray; switch (format) { case HeightfileFormat.R8: gray = bytes[i++] / 256f; pixels[j++] = new Color(gray, gray, gray); break; case HeightfileFormat.Windows: gray = (bytes[i++] + bytes[i++] * 256f) / 65535f; pixels[j++] = new Color(gray, gray, gray); break; case HeightfileFormat.Mac: gray = (bytes[i++] * 256.0f + bytes[i++]) / 65535f; pixels[j++] = new Color(gray, gray, gray); break; } } } output.SetPixels(pixels); }
private static void ValidateHeightmapRaw(byte[] input, int outputResolution, HeightfileFormat format) { int bytesPerPixel = (format == HeightfileFormat.R8 ? 1 : 2); int inputResolution = GetHeightmapResolution(input, format); int inputPixels = inputResolution * inputResolution * bytesPerPixel; if (inputResolution != outputResolution) { throw new ArgumentException(String.Format("The input file resolution {0} does not match the output resolution {1}", inputResolution, outputResolution)); } if (input.Length != inputPixels) { throw new ArgumentException("The specified HeightFileFormat does not match the file. Expected size does not match."); } }
public static void LoadRawFileAsFloats(string fileName, ref float[,] output, HeightfileFormat format, bool flipX, bool flipY) { if (!File.Exists(fileName)) { throw new FileNotFoundException("Heightmap file does not exist: " + fileName); } // Todo: we allocate a byte array, and then a float array. Can we do allocation for just one, and then reinterpret? byte[] input = File.ReadAllBytes(fileName); int resolution = GetHeightmapResolution(input, format); ValidateHeightmapRaw(input, output.GetLength(0), format); // Parse bytebuffer into floats, taking care of mirroring and byte format // Todo: replace in-loop switch with a Func<> lookup to avoid branching int i = 0; for (int x = 0; x < resolution; x++) { for (int y = 0; y < resolution; y++) { int iX = flipY ? resolution - 1 - x : x; int iY = flipX ? resolution - 1 - y : y; switch (format) { case HeightfileFormat.R8: output[iX, iY] = input[i++] / 256f; break; case HeightfileFormat.Windows: output[iX, iY] = (input[i++] + input[i++] * 256f) / 65535f; break; case HeightfileFormat.Mac: output[iX, iY] = (input[i++] * 256.0f + input[i++]) / 65535f; break; } } } }
public static void ParseHeightmapFileToTerrain(string path, TerrainData terrainData, HeightfileFormat format, bool flipX, bool flipY) { if (path == "") { Debug.LogError("Path is empty"); return; } if (terrainData == null) { Debug.LogError("Terraindata is null"); return; } var heightData = new float[terrainData.heightmapWidth, terrainData.heightmapWidth]; LoadRawFileAsFloats(path, ref heightData, format, flipX, flipY); if (heightData != null) { terrainData.SetHeights(0, 0, heightData); } }
public static int GetHeightmapResolution(byte[] bytes, HeightfileFormat format) { int bytesPerPixel = (format == HeightfileFormat.R8 ? 1 : 2); return((int)Math.Sqrt(bytes.Length / bytesPerPixel)); }