From 335bae4e782e8ac6427217aa9f48129e25d409cd Mon Sep 17 00:00:00 2001 From: Richard Crockford Date: Tue, 10 Mar 2020 10:37:16 +0000 Subject: [PATCH] Added RSS heightmap PQSMod --- .../Plugins/RealSolarSystem.dll | Bin 20992 -> 35840 bytes Source/KopernicusMods/MapSODemandLarge.cs | 1029 +++++++++++++++++ .../PQSMod_VertexHeightMapRSS.cs | 28 + Source/KopernicusMods/VertexHeightMapRSS.cs | 47 + Source/Properties/AssemblyInfo.cs | 3 + Source/RealSolarSystem.csproj | 17 +- 6 files changed, 1120 insertions(+), 4 deletions(-) create mode 100644 Source/KopernicusMods/MapSODemandLarge.cs create mode 100644 Source/KopernicusMods/PQSMod_VertexHeightMapRSS.cs create mode 100644 Source/KopernicusMods/VertexHeightMapRSS.cs diff --git a/GameData/RealSolarSystem/Plugins/RealSolarSystem.dll b/GameData/RealSolarSystem/Plugins/RealSolarSystem.dll index 82b7f2b681c36a473789c03f69f605503d36e260..c9ce7272011ee6e6b7decd1e548a1727ce867bd1 100644 GIT binary patch literal 35840 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 literal 20992 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 + /// MapSO Replacement to support Texture streaming and textures larger than 16k + /// + public class MapSODemandLarge : MapSO, ILoadOnDemand + { + // Representation of the map + private NativeByteArray Image { get; set; } + + // States + public Boolean IsLoaded { get; set; } + public Boolean AutoLoad { get; set; } + + // Path of the Texture + public String Path { get; set; } + + // Name + String ILoadOnDemand.Name + { + get { return name; } + set { name = value; } + } + + // These textures are potentially too big to make a Texture2D of, so just load directly into the byte array + private void LoadTexture(String path) + { + path = KSPUtil.ApplicationRootPath + "GameData/" + path; + if (File.Exists(path)) + { + try + { + if (path.ToLower().EndsWith(".dds")) + { + // Borrowed from stock KSP 1.0 DDS loader (hi Mike!) + // Also borrowed the extra bits from Sarbian. + BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); + UInt32 num = binaryReader.ReadUInt32(); + if (num == DDSValues.uintMagic) + { + + DDSHeader ddsHeader = new DDSHeader(binaryReader); + + if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDX10) + { + // ReSharper disable once ObjectCreationAsStatement + new DDSHeaderDX10(binaryReader); + } + + Boolean alpha = (ddsHeader.ddspf.dwFlags & 0x00000002) != 0; + Boolean fourcc = (ddsHeader.ddspf.dwFlags & 0x00000004) != 0; + Boolean rgb = (ddsHeader.ddspf.dwFlags & 0x00000040) != 0; + Boolean alphapixel = (ddsHeader.ddspf.dwFlags & 0x00000001) != 0; + Boolean luminance = (ddsHeader.ddspf.dwFlags & 0x00020000) != 0; + + Boolean mipmap = (ddsHeader.dwCaps & DDSPixelFormatCaps.MIPMAP) != 0u; + if (fourcc) + { + Debug.Log("[Kopernicus]: Compressed textures are not are supported for large maps."); + } + else + { + TextureFormat textureFormat = TextureFormat.ARGB32; + Boolean ok = true; + if (!rgb && alpha != luminance && (ddsHeader.ddspf.dwRGBBitCount == 8 || ddsHeader.ddspf.dwRGBBitCount == 16)) + { + if (ddsHeader.ddspf.dwRGBBitCount == 8) + { + // A8 format or Luminance 8 + if (alpha) + textureFormat = TextureFormat.Alpha8; + else + textureFormat = TextureFormat.R8; + } + else if (ddsHeader.ddspf.dwRGBBitCount == 16) + { + // R16 format + textureFormat = TextureFormat.R16; + } + } + else + { + ok = false; + Debug.Log("[Kopernicus]: Only A8, R8, and R16 are supported"); + } + + if (ok) + { + _name = name; + _width = (Int32)ddsHeader.dwWidth; + _height = (Int32)ddsHeader.dwHeight; + _isCompiled = false; + + if (textureFormat == TextureFormat.R16) + _bpp = (Int32)MapDepth.HeightAlpha; + else + _bpp = (Int32)MapDepth.Greyscale; + + _rowWidth = _width * _bpp; + + Int32 dataSize = _rowWidth * _height; + + Image = new NativeByteArray(dataSize); + byte[] ddsData = binaryReader.ReadBytes(dataSize); + + for (Int32 i = 0; i < dataSize; i++) + { + Image[i] = ddsData[i]; + } + + Debug.Log("[Kopernicus]: Loaded large map: " + path); + } + } + } + else + { + Debug.Log("[Kopernicus]: Bad DDS header."); + } + } + else + { + Debug.Log("[Kopernicus]: Only DDS is supported for large maps."); + } + } + catch (Exception ex) + { + Debug.Log("[Kopernicus]: failed to load " + path + " with exception " + ex.Message); + } + } + else + { + Debug.Log("[Kopernicus]: texture does not exist! " + path); + } + } + + /// + /// Load the Map + /// + public void Load() + { + // Check if the Map is already loaded + if (IsLoaded) + { + return; + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + // Load the Map + LoadTexture(Path); + + IsLoaded = true; + + // Create a dummy map for firing events + MapSODemand eventMap = (MapSODemand)ScriptableObject.CreateInstance(typeof(MapSODemand)); + eventMap.name = name; + eventMap.Path = Path; + Events.OnMapSOLoad.Fire(eventMap); + + Debug.Log("[OD] ---> Map " + name + " enabling self. Path = " + Path); + return; + } + + // Return nothing + Debug.Log("[OD] ERROR: Failed to load map " + name + " at path " + Path); + } + + /// + /// Unload the map + /// + public void Unload() + { + // We can only destroy the map, if it is loaded + if (!IsLoaded) + { + return; + } + + // Nuke the map + if (OnDemandStorage.UseManualMemoryManagement) + { + Image.Free(); + } + + // Set flags + IsLoaded = false; + + // Create a dummy map for firing events + MapSODemand eventMap = (MapSODemand)ScriptableObject.CreateInstance(typeof(MapSODemand)); + eventMap.name = name; + eventMap.Path = Path; + Events.OnMapSOUnload.Fire(eventMap); + + // Log + Debug.Log("[OD] <--- Map " + name + " disabling self. Path = " + Path); + } + + // GetPixelByte + public override Byte GetPixelByte(Int32 x, Int32 y) + { + // If we aren't loaded.... + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelbyte with unloaded map " + name + " of path " + Path + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return 0; + } + } + + if (!OnDemandStorage.UseManualMemoryManagement) + { + return 0; + } + + if (x < 0) + { + x = Width - x; + } + else if (x >= Width) + { + x -= Width; + } + + if (y < 0) + { + y = Height - y; + } + else if (y >= Height) + { + y -= Height; + } + + return Image[PixelIndex(x, y)]; + } + + // GetPixelColor - Double + public override Color GetPixelColor(Double x, Double y) + { + if (IsLoaded) + { + return base.GetPixelColor(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelColD with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return Color.black; + } + + return base.GetPixelColor(x, y); + } + + // GetPixelColor - Float + public override Color GetPixelColor(Single x, Single y) + { + if (IsLoaded) + { + return base.GetPixelColor(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelColF with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return Color.black; + } + + return base.GetPixelColor(x, y); + } + + // GetPixelColor - Int + public override Color GetPixelColor(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelColI with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return Color.black; + } + } + + if (!OnDemandStorage.UseManualMemoryManagement) + { + return new Color(); + } + + index = PixelIndex(x, y); + switch (_bpp) + { + case 3: + return new Color(Byte2Float * Image[index], Byte2Float * Image[index + 1], + Byte2Float * Image[index + 2], 1f); + case 4: + return new Color(Byte2Float * Image[index], Byte2Float * Image[index + 1], + Byte2Float * Image[index + 2], Byte2Float * Image[index + 3]); + } + + if (_bpp != 2) + { + retVal = Byte2Float * Image[index]; + return new Color(retVal, retVal, retVal, 1f); + } + + retVal = Byte2Float * Image[index]; + return new Color(retVal, retVal, retVal, Byte2Float * Image[index + 1]); + } + + // GetPixelColor32 - Double + public override Color GetPixelColor32(Double x, Double y) + { + if (IsLoaded) + { + return base.GetPixelColor32(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelCol32D with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return Color.black; + } + + return base.GetPixelColor32(x, y); + } + + // GetPixelColor32 - Float - Honestly Squad, why are they named GetPixelColor32, but return normal Colors instead of Color32? + public override Color GetPixelColor32(Single x, Single y) + { + if (IsLoaded) + { + return base.GetPixelColor32(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelCol32F with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return Color.black; + } + + return base.GetPixelColor32(x, y); + } + + // GetPixelColor32 - Int + public override Color32 GetPixelColor32(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelCol32I with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Color32(); + } + } + + if (!OnDemandStorage.UseManualMemoryManagement) + { + return new Color32(); + } + + index = PixelIndex(x, y); + switch (_bpp) + { + case 3: + return new Color32(Image[index], Image[index + 1], Image[index + 2], 255); + case 4: + return new Color32(Image[index], Image[index + 1], Image[index + 2], Image[index + 3]); + } + + if (_bpp != 2) + { + val = Image[index]; + return new Color32(val, val, val, 255); + } + + val = Image[index]; + return new Color32(val, val, val, Image[index + 1]); + } + + // GetPixelFloat - Double + public override Single GetPixelFloat(Double x, Double y) + { + if (IsLoaded) + { + return base.GetPixelFloat(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelFloatD with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return 0f; + } + + return base.GetPixelFloat(x, y); + } + + // GetPixelFloat - Float + public override Single GetPixelFloat(Single x, Single y) + { + if (IsLoaded) + { + return base.GetPixelFloat(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelFloatF with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return 0f; + } + + return base.GetPixelFloat(x, y); + } + + // GetPixelFloat - Integer + public override Single GetPixelFloat(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelFloatI with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return 0f; + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + retVal = 0f; + index = PixelIndex(x, y); + for (Int32 i = 0; i < _bpp; i++) + { + retVal += Image[index + i]; + } + + retVal /= _bpp; + retVal *= Byte2Float; + return retVal; + } + + return 0f; + } + + // GetPixelHeightAlpha - Double + public override HeightAlpha GetPixelHeightAlpha(Double x, Double y) + { + if (IsLoaded) + { + return base.GetPixelHeightAlpha(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelHeightAlphaD with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new HeightAlpha(0f, 0f); + } + + return base.GetPixelHeightAlpha(x, y); + } + + // GetPixelHeightAlpha - Float + public override HeightAlpha GetPixelHeightAlpha(Single x, Single y) + { + if (IsLoaded) + { + return base.GetPixelHeightAlpha(x, y); + } + + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelHeightAlphaF with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new HeightAlpha(0f, 0f); + } + + return base.GetPixelHeightAlpha(x, y); + } + + // GetPixelHeightAlpha - Int + public override HeightAlpha GetPixelHeightAlpha(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelHeightAlphaI with unloaded map " + name + " of path " + + Path + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new HeightAlpha(0f, 0f); + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + index = PixelIndex(x, y); + if (_bpp == 2) + { + return new HeightAlpha(Byte2Float * Image[index], Byte2Float * Image[index + 1]); + } + + if (_bpp != 4) + { + return new HeightAlpha(Byte2Float * Image[index], 1f); + } + + val = Image[index]; + return new HeightAlpha(Byte2Float * Image[index], Byte2Float * Image[index + 3]); + } + + return new HeightAlpha(0f, 0f); + } + + // GreyByte + public override Byte GreyByte(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting GreyByteI with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return 0; + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + return Image[PixelIndex(x, y)]; + } + + return 0; + } + + // GreyFloat + public override Single GreyFloat(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting GreyFloat with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return 0f; + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + return Byte2Float * Image[PixelIndex(x, y)]; + } + + return 0f; + } + + // PixelByte + public override Byte[] PixelByte(Int32 x, Int32 y) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: getting pixelByte with unloaded map " + name + " of path " + Path + + ", autoload = " + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Byte[_bpp]; + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + Byte[] numArray = new Byte[_bpp]; + index = PixelIndex(x, y); + for (Int32 i = 0; i < _bpp; i++) + { + numArray[i] = Image[index + i]; + } + + return numArray; + } + + return new Byte[_bpp]; + } + + // CompileToTexture + public override Texture2D CompileToTexture(Byte filter) + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: compiling with unloaded map " + name + " of path " + Path + ", autoload = " + + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Texture2D(_width, _height); + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + Color32[] color32 = new Color32[Size]; + for (Int32 i = 0; i < Size; i++) + { + val = (Byte)((Image[i] & filter) == 0 ? 0 : 255); + color32[i] = new Color32(val, val, val, 255); + } + + Texture2D compiled = new Texture2D(Width, Height, TextureFormat.RGB24, false); + compiled.SetPixels32(color32); + compiled.Apply(false, true); + return compiled; + } + return new Texture2D(_width, _height); + } + + // Generate a greyscale texture from the stored data + public override Texture2D CompileGreyscale() + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: compiling with unloaded map " + name + " of path " + Path + ", autoload = " + + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Texture2D(_width, _height); + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + Color32[] color32 = new Color32[Size]; + for (Int32 i = 0; i < Size; i++) + { + val = Image[i]; + color32[i] = new Color32(val, val, val, 255); + } + + Texture2D compiled = new Texture2D(Width, Height, TextureFormat.RGB24, false); + compiled.SetPixels32(color32); + compiled.Apply(false, true); + return compiled; + } + return new Texture2D(_width, _height); + } + + // Generate a height/alpha texture from the stored data + public override Texture2D CompileHeightAlpha() + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: compiling with unloaded map " + name + " of path " + Path + ", autoload = " + + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Texture2D(_width, _height); + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + Color32[] color32 = new Color32[Width * Height]; + for (Int32 i = 0; i < Width * Height; i++) + { + val = Image[i * 2]; + color32[i] = new Color32(val, val, val, Image[i * 2 + 1]); + } + + Texture2D compiled = new Texture2D(Width, Height, TextureFormat.RGB24, false); + compiled.SetPixels32(color32); + compiled.Apply(false, true); + return compiled; + } + return new Texture2D(_width, _height); + } + + // Generate an RGB texture from the stored data + public override Texture2D CompileRGB() + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: compiling with unloaded map " + name + " of path " + Path + ", autoload = " + + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Texture2D(_width, _height); + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + Color32[] color32 = new Color32[Width * Height]; + for (Int32 i = 0; i < Width * Height; i++) + { + color32[i] = new Color32(Image[i * 3], Image[i * 3 + 1], Image[i * 3 + 2], 255); + } + + Texture2D compiled = new Texture2D(Width, Height, TextureFormat.RGB24, false); + compiled.SetPixels32(color32); + compiled.Apply(false, true); + return compiled; + } + return new Texture2D(_width, _height); + } + + // Generate an RGBA texture from the stored data + public override Texture2D CompileRGBA() + { + if (!IsLoaded) + { + if (OnDemandStorage.OnDemandLogOnMissing) + { + Debug.Log("[OD] ERROR: compiling with unloaded map " + name + " of path " + Path + ", autoload = " + + AutoLoad); + } + + if (AutoLoad) + { + Load(); + } + else + { + return new Texture2D(_width, _height); + } + } + + if (OnDemandStorage.UseManualMemoryManagement) + { + Color32[] color32 = new Color32[Width * Height]; + for (Int32 i = 0; i < Width * Height; i++) + { + color32[i] = new Color32(Image[i * 3], Image[i * 3 + 1], Image[i * 3 + 2], Image[i * 3 + 3]); + } + + Texture2D compiled = new Texture2D(Width, Height, TextureFormat.RGB24, false); + compiled.SetPixels32(color32); + compiled.Apply(false, true); + return compiled; + } + return new Texture2D(_width, _height); + } + } + + // Parser for a MapSO + [RequireConfigType(ConfigType.Value)] + public class MapSOParserLarge : BaseLoader, IParsable, ITypeParser where T : MapSO + { + /// + /// The value that is being parsed + /// + public T Value { get; set; } + + /// + /// Parse the Value from a string + /// + public void SetFromString(String s) + { + // Should we use OnDemand? + Boolean useOnDemand = OnDemandStorage.UseOnDemand; + + if (s.StartsWith("BUILTIN/")) + { + s = s.Substring(8); + Value = Utility.FindMapSO(s); + } + else + { + // are we on-demand? Don't load now. + if (useOnDemand && typeof(T) == typeof(MapSO)) + { + if (!Utility.TextureExists(s)) + { + return; + } + + + MapSODemandLarge map = ScriptableObject.CreateInstance(); + map.Path = s; + map.AutoLoad = OnDemandStorage.OnDemandLoadOnMissing; + OnDemandStorage.AddMap(generatedBody.name, map); + Value = map as T; + } + else // Load the texture + { + MapSODemandLarge map = ScriptableObject.CreateInstance(); + map.Path = s; + map.AutoLoad = false; + OnDemandStorage.AddMap(generatedBody.name, map); + Value = map as T; + } + } + + if (Value != null) + { + Value.name = s; + } + } + + /// + /// Convert the value to a parsable String + /// + public String ValueToString() + { + if (Value == null) + { + return null; + } + + if (GameDatabase.Instance.ExistsTexture(Value.name) || OnDemandStorage.TextureExists(Value.name)) + { + return Value.name; + } + + return "BUILTIN/" + Value.name; + } + + /// + /// Create a new MapSOParser_HeightAlpha + /// + public MapSOParserLarge() + { + + } + + /// + /// Create a new MapSOParser_HeightAlpha from an already existing Texture + /// + public MapSOParserLarge(T value) + { + Value = value; + } + + /// + /// Convert Parser to Value + /// + public static implicit operator T(MapSOParserLarge parser) + { + return parser.Value; + } + + /// + /// Convert Value to Parser + /// + public static implicit operator MapSOParserLarge(T value) + { + return new MapSOParserLarge(value); + } + } +} diff --git a/Source/KopernicusMods/PQSMod_VertexHeightMapRSS.cs b/Source/KopernicusMods/PQSMod_VertexHeightMapRSS.cs new file mode 100644 index 00000000..460b01da --- /dev/null +++ b/Source/KopernicusMods/PQSMod_VertexHeightMapRSS.cs @@ -0,0 +1,28 @@ +/* + * This code is adapted from KopernicusExpansion-Continued + * Available from https://github.com/StollD/KopernicusExpansion-Continued + */ + +using System; +using UnityEngine; + +namespace RealSolarSystem +{ + /// + /// A heightmap PQSMod that can parse encoded 16bpp textures + /// + public class PQSMod_VertexHeightMapRSS : PQSMod_VertexHeightMap + { + public override void OnVertexBuildHeight(PQS.VertexBuildData data) + { + // Get the HeightAlpha, not the Float-Value from the Map + MapSO.HeightAlpha ha = heightMap.GetPixelHeightAlpha(data.u, data.v); + + // Get the height data from the terrain + Double height = (ha.height + ha.alpha * (Double)Byte.MaxValue) / (Double)(Byte.MaxValue + 1); + + // Apply it + data.vertHeight += heightMapOffset + heightMapDeformity * height; + } + } +} diff --git a/Source/KopernicusMods/VertexHeightMapRSS.cs b/Source/KopernicusMods/VertexHeightMapRSS.cs new file mode 100644 index 00000000..c15ec173 --- /dev/null +++ b/Source/KopernicusMods/VertexHeightMapRSS.cs @@ -0,0 +1,47 @@ +/* + * This code is adapted from KopernicusExpansion-Continued + * Available from https://github.com/StollD/KopernicusExpansion-Continued + */ + +using System; +using Kopernicus.ConfigParser.Attributes; +using Kopernicus.ConfigParser.BuiltinTypeParsers; +using Kopernicus.Configuration.ModLoader; + +namespace RealSolarSystem +{ + public class VertexHeightMapRSS : ModLoader + { + // The map texture for the planet + [ParserTarget("map")] + public MapSOParserLarge heightMap + { + get { return Mod.heightMap; } + set { Mod.heightMap = value; } + } + + // Height map offset + [ParserTarget("offset")] + public NumericParser heightMapOffset + { + get { return Mod.heightMapOffset; } + set { Mod.heightMapOffset = value; } + } + + // Height map offset + [ParserTarget("deformity")] + public NumericParser heightMapDeformity + { + get { return Mod.heightMapDeformity; } + set { Mod.heightMapDeformity = value; } + } + + // Height map offset + [ParserTarget("scaleDeformityByRadius")] + public NumericParser scaleDeformityByRadius + { + get { return Mod.scaleDeformityByRadius; } + set { Mod.scaleDeformityByRadius = value; } + } + } +} \ No newline at end of file diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs index d2dc38d3..caad8356 100644 --- a/Source/Properties/AssemblyInfo.cs +++ b/Source/Properties/AssemblyInfo.cs @@ -38,3 +38,6 @@ [assembly: AssemblyVersion("0.18.0.0")] [assembly: AssemblyFileVersion("0.18.0.0")] + +[assembly: KSPAssemblyDependency("Kopernicus", 1, 0)] +[assembly: KSPAssemblyDependency("Kopernicus.Parser", 1, 0)] \ No newline at end of file diff --git a/Source/RealSolarSystem.csproj b/Source/RealSolarSystem.csproj index 9701f01c..9e187f7d 100644 --- a/Source/RealSolarSystem.csproj +++ b/Source/RealSolarSystem.csproj @@ -11,7 +11,7 @@ Properties RealSolarSystem RealSolarSystem - v4.7.1 + v4.7.2 512 @@ -42,6 +42,9 @@ + + + @@ -51,12 +54,21 @@ False + + False + + + False + False False + + False + False @@ -71,9 +83,6 @@ - - del "System.Core.dll" -