private float SampleHeightBilinear(MyHeightmapFace map, float lodSize, float s, float t, int sx, int sy, out Vector3 Normal) { float value; float lodMapSize = lodSize * m_pixelSizeRecip2; // Bilinear sampling float fx = 1 - s, fy = 1 - t; int sx1 = Math.Min(sx + (int)Math.Ceiling(lodMapSize), m_heightmap.Resolution); int sy1 = Math.Min(sy + (int)Math.Ceiling(lodMapSize), m_heightmap.Resolution); float h00 = map.GetValuef(sx, sy); float h10 = map.GetValuef(sx1, sy); float h01 = map.GetValuef(sx, sy1); float h11 = map.GetValuef(sx1, sy1); value = h00 * fx * fy; value += h10 * s * fy; value += h01 * fx * t; value += h11 * s * t; float zx = (h10 - h00) * fy + (h11 - h01) * t; float zy = (h01 - h00) * fx + (h11 - h10) * s; Normal = new Vector3(m_mapStepScale * zx, m_mapStepScale * zy, m_mapStepScaleSquare); Normal.Normalize(); return(value); }
private static void PrepareHeightMap8Bit(MyHeightmapFace map, PixelBuffer imageData) { for (int y = 0; y < map.Resolution; y++) { for (int x = 0; x < map.Resolution; x++) { map.SetValue(x, y, (ushort)(imageData.GetPixel <byte>(x, y) * 256)); } } }
/** * Calculate cell for the coefficient cache. */ private unsafe void CalculateCacheCell(MyHeightmapFace map, Cache.Cell *cell, bool compouteBounds = false) { int sx = cell->Coord.X; int sy = cell->Coord.Y; fixed(float *row = &s_Cz.M11) { int linear = map.GetRowStart(sy - 1) + sx - 1; fixed(ushort *texture = map.Data) { map.Get4Row(linear, row, texture); linear += map.RowStride; map.Get4Row(linear, row + 4, texture); linear += map.RowStride; map.Get4Row(linear, row + 8, texture); linear += map.RowStride; map.Get4Row(linear, row + 12, texture); Matrix.Multiply(ref CR, ref s_Cz, out cell->Gz); Matrix.Multiply(ref cell->Gz, ref CRT, out cell->Gz); if (compouteBounds) { float Min = float.PositiveInfinity; float Max = float.NegativeInfinity; Matrix heights; Matrix.Multiply(ref BInv, ref cell->Gz, out heights); Matrix.Multiply(ref heights, ref BInvT, out heights); /* Will do good old pointer magic */ float *values = &heights.M11; for (int i = 0; i < 16; ++i) { if (Max < values[i]) { Max = values[i]; } if (Min > values[i]) { Min = values[i]; } } cell->Max = Max; cell->Min = Min; } else { cell->Max = 1; cell->Min = 0; } } } }
private static void PrepareHeightMap(MyHeightmapFace map, PixelBuffer imageData) { IntPtr mapData = imageData.DataPointer; var rowStride = imageData.RowStride; for (int y = 0; y < map.Resolution; y++) { Utilities.Read(mapData, map.Data, map.GetRowStart(y), imageData.Width); //imageData.GetPixels<ushort>(map.Data, y, map.GetRowStart(y), imageData.Width); this has a bug, see sharpdx source and be amused mapData += rowStride; } }
public MyHeightmapFace GetHeightMap(string folderName, string faceName, MyModContext context) { ProfilerShort.Begin("MyHeightmapLoadingSystem::GetHeightMap()"); if (m_first) { PreloadCrashingData(); m_first = false; } string fullPath = null; bool found = false; // Look for modded textures if (!context.IsBaseGame) { fullPath = Path.Combine(Path.Combine(context.ModPathData,"PlanetDataFiles"), folderName, faceName); if (MyFileSystem.FileExists(fullPath + ".png")) { found = true; fullPath += ".png"; } else if (MyFileSystem.FileExists(fullPath + ".dds")) { found = true; fullPath += ".dds"; } } // Use default ones if (!found) { fullPath = Path.Combine(m_planetDataFolder, folderName, faceName); if (MyFileSystem.FileExists(fullPath + ".png")) { found = true; fullPath += ".png"; } else if (MyFileSystem.FileExists(fullPath + ".dds")) { fullPath += ".dds"; } } MyHeightmapFace value; if (m_heightMaps.TryGetValue(fullPath, out value)) { ProfilerShort.End(); return value; } try { using (SharpDXImage image = LoadTexture(fullPath)) { if (image == null) { MyLog.Default.WriteLine("Could not load texture {0}, no suitable format found. " + fullPath); } else { PixelBuffer buffer = image.GetPixelBuffer(0, 0, 0); value = new MyHeightmapFace(buffer.Height); if (buffer.Format == Format.R16_UNorm) { PrepareHeightMap(value, buffer); } else if (buffer.Format == Format.R8_UNorm) { PrepareHeightMap8Bit(value, buffer); } else { MyDebug.FailRelease(String.Format("Heighmap texture {0}: Invalid format {1} (expecting R16_UNorm or R8_UNorm).", fullPath, buffer.Format)); } buffer = null; image.Dispose(); } } m_heightMaps[fullPath] = value; } catch (Exception e) { MyLog.Default.WriteLine(e.Message); } ProfilerShort.End(); return value; }
private static void PrepareHeightMap8Bit(MyHeightmapFace map, PixelBuffer imageData) { for (int y = 0; y < map.Resolution; y++) { for (int x = 0; x < map.Resolution; x++) { map.SetValue(x, y, (ushort)(imageData.GetPixel<byte>(x, y) * 256)); } } }
private unsafe void CalculateCacheCell(MyHeightmapFace map, Cache.Cell *cell, bool compouteBounds = false) { ushort *numPtr2; ushort[] pinned numArray; int x = cell.Coord.X; int y = cell.Coord.Y; float *values = &s_Cz.M11; int linearOfft = (map.GetRowStart(y - 1) + x) - 1; if (((numArray = map.Data) == null) || (numArray.Length == 0)) { numPtr2 = null; } else { numPtr2 = numArray; } map.Get4Row(linearOfft, values, numPtr2); linearOfft += map.RowStride; map.Get4Row(linearOfft, values + (4 * 4), numPtr2); linearOfft += map.RowStride; map.Get4Row(linearOfft, values + (8 * 4), numPtr2); linearOfft += map.RowStride; map.Get4Row(linearOfft, values + (12 * 4), numPtr2); Matrix.Multiply(ref CR, ref s_Cz, out cell.Gz); Matrix.Multiply(ref cell.Gz, ref CRT, out cell.Gz); if (!compouteBounds) { cell.Max = 1f; cell.Min = 0f; } else { Matrix matrix; float positiveInfinity = float.PositiveInfinity; float negativeInfinity = float.NegativeInfinity; Matrix.Multiply(ref BInv, ref cell.Gz, out matrix); Matrix *matrixPtr1 = (Matrix *)ref matrix; Matrix.Multiply(ref (Matrix) ref matrixPtr1, ref BInvT, out matrix); float *numPtr3 = &matrix.M11; int num6 = 0; while (true) { if (num6 >= 0x10) { cell.Max = negativeInfinity; cell.Min = positiveInfinity; break; } if (negativeInfinity < numPtr3[num6 * 4]) { negativeInfinity = numPtr3[num6 * 4]; } if (positiveInfinity > numPtr3[num6 * 4]) { positiveInfinity = numPtr3[num6 * 4]; } num6++; } } numArray = null; fixed(float *numRef = null) { return; } }
private float SampleHeightBilinear(MyHeightmapFace map, float lodSize, float s, float t, int sx, int sy, out Vector3 Normal) { float value; float lodMapSize = lodSize * m_pixelSizeRecip2; // Bilinear sampling float fx = 1 - s, fy = 1 - t; int sx1 = Math.Min(sx + (int)Math.Ceiling(lodMapSize), m_heightmap.Resolution); int sy1 = Math.Min(sy + (int)Math.Ceiling(lodMapSize), m_heightmap.Resolution); float h00 = map.GetValuef(sx, sy); float h10 = map.GetValuef(sx1, sy); float h01 = map.GetValuef(sx, sy1); float h11 = map.GetValuef(sx1, sy1); value = h00 * fx * fy; value += h10 * s * fy; value += h01 * fx * t; value += h11 * s * t; float zx = (h10 - h00) * fy + (h11 - h01) * t; float zy = (h01 - h00) * fx + (h11 - h10) * s; Normal = new Vector3(m_mapStepScale * zx, m_mapStepScale * zy, m_mapStepScaleSquare); Normal.Normalize(); return value; }
/** * Calculate cell for the coefficient cache. */ private unsafe void CalculateCacheCell(MyHeightmapFace map, Cache.Cell* cell, bool compouteBounds = false) { int sx = cell->Coord.X; int sy = cell->Coord.Y; fixed (float* row = &s_Cz.M11) { int linear = map.GetRowStart(sy - 1) + sx - 1; fixed (ushort* texture = map.Data) { map.Get4Row(linear, row, texture); linear += map.RowStride; map.Get4Row(linear, row + 4, texture); linear += map.RowStride; map.Get4Row(linear, row + 8, texture); linear += map.RowStride; map.Get4Row(linear, row + 12, texture); Matrix.Multiply(ref CR, ref s_Cz, out cell->Gz); Matrix.Multiply(ref cell->Gz, ref CRT, out cell->Gz); if (compouteBounds) { float Min = float.PositiveInfinity; float Max = float.NegativeInfinity; Matrix heights; Matrix.Multiply(ref BInv, ref cell->Gz, out heights); Matrix.Multiply(ref heights, ref BInvT, out heights); /* Will do good old pointer magic */ float* values = &heights.M11; for (int i = 0; i < 16; ++i) { if (Max < values[i]) Max = values[i]; if (Min > values[i]) Min = values[i]; } cell->Max = Max; cell->Min = Min; } else { cell->Max = 1; cell->Min = 0; } } } }
public MyHeightmapFace GetHeightMap(string folderName, string faceName, MyModContext context) { ProfilerShort.Begin("MyHeightmapLoadingSystem::GetHeightMap()"); if (m_first) { PreloadCrashingData(); m_first = false; } string fullPath = null; bool found = false; // Look for modded textures if (!context.IsBaseGame) { fullPath = Path.Combine(Path.Combine(context.ModPathData, "PlanetDataFiles"), folderName, faceName); if (MyFileSystem.FileExists(fullPath + ".png")) { found = true; fullPath += ".png"; } else if (MyFileSystem.FileExists(fullPath + ".dds")) { found = true; fullPath += ".dds"; } } // Use default ones if (!found) { fullPath = Path.Combine(m_planetDataFolder, folderName, faceName); if (MyFileSystem.FileExists(fullPath + ".png")) { found = true; fullPath += ".png"; } else if (MyFileSystem.FileExists(fullPath + ".dds")) { fullPath += ".dds"; } } MyHeightmapFace value; if (m_heightMaps.TryGetValue(fullPath, out value)) { ProfilerShort.End(); return(value); } try { using (SharpDXImage image = LoadTexture(fullPath)) { if (image == null) { MyLog.Default.WriteLine("Could not load texture {0}, no suitable format found. " + fullPath); } else { PixelBuffer buffer = image.GetPixelBuffer(0, 0, 0); value = new MyHeightmapFace(buffer.Height); if (buffer.Format == Format.R16_UNorm) { PrepareHeightMap(value, buffer); } else if (buffer.Format == Format.R8_UNorm) { PrepareHeightMap8Bit(value, buffer); } else { MyDebug.FailRelease(String.Format("Heighmap texture {0}: Invalid format {1} (expecting R16_UNorm or R8_UNorm).", fullPath, buffer.Format)); } buffer = null; } } m_heightMaps[fullPath] = value; } catch (Exception e) { MyLog.Default.WriteLine(e.Message); } ProfilerShort.End(); return(value); }