From 2c9f1cd7c42be34e0318e245b116086bff2a8408 Mon Sep 17 00:00:00 2001 From: Paul Hirch Date: Thu, 9 May 2024 20:17:30 +0200 Subject: [PATCH] refactor --- Assets/Grille.BeamNG.ico | Bin 0 -> 21238 bytes Assets/Grille.BeamNG.png | Bin 0 -> 15914 bytes Grille.BeamNGLib/Collections/IKeyed.cs | 6 + .../Collections/KeyedCollection.cs | 27 ++-- Grille.BeamNGLib/Grille.BeamNgLib.csproj | 29 ++++ Grille.BeamNGLib/IO/Binary/TerrainBinary.cs | 39 +++++ .../IO/JsonDictSerializer.cs | 12 +- .../IO/LevelInfoSerializer.cs | 11 +- Grille.BeamNGLib/IO/Resources/FileResource.cs | 16 ++ .../IO/Resources/GroupResource.cs | 14 ++ .../IO/Resources/PathEvaluator.cs | 38 +++++ .../IO/Resources/Resource.cs | 28 ++-- .../IO/Resources/ResourceCollection.cs | 21 +++ Grille.BeamNGLib/IO/Resources/StaticPath.cs | 4 + .../IO/Resources/ZipFileResource.cs | 18 +-- Grille.BeamNGLib/IO/TerrainV9Serializer.cs | 140 ++++++++++++++++++ .../IO/ZipFileManager.cs | 10 +- Grille.BeamNGLib/Level.cs | 24 +++ .../LevelInfo.cs | 11 +- .../Logging}/ErrorLogger.cs | 10 +- Grille.BeamNGLib/Logging/Logger.cs | 85 +++++++++++ Grille.BeamNGLib/SceneTree/Art/ArtGroup.cs | 56 +++++++ .../SceneTree/Art/ArtGroupRoot.cs | 16 ++ Grille.BeamNGLib/SceneTree/Art/ArtItem.cs | 8 + .../SceneTree/Art/ForestItemData.cs | 10 +- Grille.BeamNGLib/SceneTree/Art/Material.cs | 8 + .../SceneTree/Art/MaterialLibary.cs | 45 ++++++ .../SceneTree/Art/MaterialNode.cs | 10 +- .../SceneTree/Art/ObjectMaterial.cs | 46 ++---- .../SceneTree/Art/TerrainMaterial.cs | 39 ++--- .../Art/TerrainMaterialTextureSet.cs | 11 +- .../SceneTree/JsonDictProperty.cs | 20 +-- .../SceneTree/JsonDictWrapper.cs | 42 ++---- .../SceneTree/Main/GroundCover.cs | 21 +-- .../SceneTree/Main/GroundCoverInstance.cs | 19 +-- .../SceneTree/Main/SimGroup.cs | 42 +++--- .../SceneTree/Main/SimGroupLevelObjects.cs | 10 +- .../SceneTree/Main/SimGroupMissionGroup.cs | 10 +- .../SceneTree/Main/SimGroupRoot.cs | 10 +- .../SceneTree/Main/SimItem.cs | 11 +- .../SceneTree/Main/SpawnSphere.cs | 10 +- .../SceneTree/Main/TerrainBlock.cs | 10 +- .../TerrainInfo.cs | 12 +- Grille.BeamNGLib/usings.cs | 6 + .../Grille.BeamNgLib_Tests.csproj | 18 +++ Grille.BeamNGLib_Tests/Program.cs | 13 ++ Grille.BeamNGLib_Tests/Terrain.cs | 72 +++++++++ Grille.BeamNGLib_Tests/Utils.cs | 16 ++ Grille.BeamNGLib_Tests/usings.cs | 5 + LICENSE | 21 +++ LevelTemplateCreator.sln | 17 ++- LevelTemplateCreator/Assets/Asset.cs | 52 ++++--- .../Assets/AssetCollection.cs | 4 +- LevelTemplateCreator/Assets/AssetLibary.cs | 11 +- .../Assets/AssetLibaryContent.cs | 7 +- .../Assets/AssetLibaryLoader.cs | 22 +-- .../Assets/{AssetInfo.cs => AssetSource.cs} | 2 +- .../Assets/GroundCoverAsset.cs | 13 +- .../Assets/GroundCoverBuilder.cs | 9 +- .../Assets/LevelObjectsAsset.cs | 13 +- LevelTemplateCreator/Assets/MaterialAsset.cs | 13 +- .../Assets/ObjectMaterialAsset.cs | 23 +-- .../Assets/TerrainMaterialAsset.cs | 20 +-- LevelTemplateCreator/Collections/IKeyed.cs | 12 -- LevelTemplateCreator/EnvironmentInfo.cs | 9 +- LevelTemplateCreator/GUI/AssetViewBox.cs | 2 +- LevelTemplateCreator/GUI/LevelSettings.cs | 4 +- LevelTemplateCreator/GUI/MainForm.cs | 11 +- LevelTemplateCreator/GUI/SettingsForm.cs | 3 +- .../GUI/TerrainSettings.Designer.cs | 22 +-- LevelTemplateCreator/GUI/TerrainSettings.cs | 3 +- .../IO/Resources/FileResource.cs | 22 --- .../IO/Resources/ResourceCollection.cs | 45 ------ .../IO/Resources/ResourceManager.cs | 123 --------------- .../IO/TerrainV9Serializer.cs | 50 ------- .../{Level.cs => LevelExporter.cs} | 114 ++++++++------ .../LevelTemplateCreator.csproj | 6 +- LevelTemplateCreator/Logger.cs | 37 ----- LevelTemplateCreator/MaterialExtension.cs | 23 +++ LevelTemplateCreator/Program.cs | 5 + .../{IO/Resources => Resouces}/Constants.cs | 2 +- .../Resouces/PathExpressionEvaluator.cs | 108 ++++++++++++++ .../Resources => Resouces}/SolidColorNames.cs | 2 +- .../SolidColorResource.cs | 7 +- .../SceneTree/Art/Material.cs | 22 --- .../SceneTree/Art/MaterialLibary.cs | 94 ------------ .../SceneTree/Art/ObjectMaterialLibary.cs | 22 --- .../SceneTree/Art/TerrainMaterialLibary.cs | 39 ----- LevelTemplateCreator/usings.cs | 8 +- 89 files changed, 1212 insertions(+), 949 deletions(-) create mode 100644 Assets/Grille.BeamNG.ico create mode 100644 Assets/Grille.BeamNG.png create mode 100644 Grille.BeamNGLib/Collections/IKeyed.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/Collections/KeyedCollection.cs (78%) create mode 100644 Grille.BeamNGLib/Grille.BeamNgLib.csproj create mode 100644 Grille.BeamNGLib/IO/Binary/TerrainBinary.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/IO/JsonDictSerializer.cs (93%) rename {LevelTemplateCreator => Grille.BeamNGLib}/IO/LevelInfoSerializer.cs (80%) create mode 100644 Grille.BeamNGLib/IO/Resources/FileResource.cs create mode 100644 Grille.BeamNGLib/IO/Resources/GroupResource.cs create mode 100644 Grille.BeamNGLib/IO/Resources/PathEvaluator.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/IO/Resources/Resource.cs (53%) create mode 100644 Grille.BeamNGLib/IO/Resources/ResourceCollection.cs create mode 100644 Grille.BeamNGLib/IO/Resources/StaticPath.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/IO/Resources/ZipFileResource.cs (73%) create mode 100644 Grille.BeamNGLib/IO/TerrainV9Serializer.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/IO/ZipFileManager.cs (92%) create mode 100644 Grille.BeamNGLib/Level.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/LevelInfo.cs (68%) rename {LevelTemplateCreator/Assets => Grille.BeamNGLib/Logging}/ErrorLogger.cs (81%) create mode 100644 Grille.BeamNGLib/Logging/Logger.cs create mode 100644 Grille.BeamNGLib/SceneTree/Art/ArtGroup.cs create mode 100644 Grille.BeamNGLib/SceneTree/Art/ArtGroupRoot.cs create mode 100644 Grille.BeamNGLib/SceneTree/Art/ArtItem.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Art/ForestItemData.cs (51%) create mode 100644 Grille.BeamNGLib/SceneTree/Art/Material.cs create mode 100644 Grille.BeamNGLib/SceneTree/Art/MaterialLibary.cs rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Art/MaterialNode.cs (54%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Art/ObjectMaterial.cs (57%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Art/TerrainMaterial.cs (84%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Art/TerrainMaterialTextureSet.cs (72%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/JsonDictProperty.cs (91%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/JsonDictWrapper.cs (69%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/GroundCover.cs (56%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/GroundCoverInstance.cs (73%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/SimGroup.cs (66%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/SimGroupLevelObjects.cs (74%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/SimGroupMissionGroup.cs (61%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/SimGroupRoot.cs (51%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/SimItem.cs (66%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/SpawnSphere.cs (82%) rename {LevelTemplateCreator => Grille.BeamNGLib}/SceneTree/Main/TerrainBlock.cs (82%) rename {LevelTemplateCreator => Grille.BeamNGLib}/TerrainInfo.cs (82%) create mode 100644 Grille.BeamNGLib/usings.cs create mode 100644 Grille.BeamNGLib_Tests/Grille.BeamNgLib_Tests.csproj create mode 100644 Grille.BeamNGLib_Tests/Program.cs create mode 100644 Grille.BeamNGLib_Tests/Terrain.cs create mode 100644 Grille.BeamNGLib_Tests/Utils.cs create mode 100644 Grille.BeamNGLib_Tests/usings.cs create mode 100644 LICENSE rename LevelTemplateCreator/Assets/{AssetInfo.cs => AssetSource.cs} (69%) delete mode 100644 LevelTemplateCreator/Collections/IKeyed.cs delete mode 100644 LevelTemplateCreator/IO/Resources/FileResource.cs delete mode 100644 LevelTemplateCreator/IO/Resources/ResourceCollection.cs delete mode 100644 LevelTemplateCreator/IO/Resources/ResourceManager.cs delete mode 100644 LevelTemplateCreator/IO/TerrainV9Serializer.cs rename LevelTemplateCreator/{Level.cs => LevelExporter.cs} (50%) delete mode 100644 LevelTemplateCreator/Logger.cs create mode 100644 LevelTemplateCreator/MaterialExtension.cs rename LevelTemplateCreator/{IO/Resources => Resouces}/Constants.cs (94%) create mode 100644 LevelTemplateCreator/Resouces/PathExpressionEvaluator.cs rename LevelTemplateCreator/{IO/Resources => Resouces}/SolidColorNames.cs (98%) rename LevelTemplateCreator/{IO/Resources => Resouces}/SolidColorResource.cs (85%) delete mode 100644 LevelTemplateCreator/SceneTree/Art/Material.cs delete mode 100644 LevelTemplateCreator/SceneTree/Art/MaterialLibary.cs delete mode 100644 LevelTemplateCreator/SceneTree/Art/ObjectMaterialLibary.cs delete mode 100644 LevelTemplateCreator/SceneTree/Art/TerrainMaterialLibary.cs diff --git a/Assets/Grille.BeamNG.ico b/Assets/Grille.BeamNG.ico new file mode 100644 index 0000000000000000000000000000000000000000..f20ca123d231de6dc94de0bd28f4409d1f8d13d9 GIT binary patch literal 21238 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 literal 0 HcmV?d00001 diff --git a/Grille.BeamNGLib/Collections/IKeyed.cs b/Grille.BeamNGLib/Collections/IKeyed.cs new file mode 100644 index 0000000..88056fb --- /dev/null +++ b/Grille.BeamNGLib/Collections/IKeyed.cs @@ -0,0 +1,6 @@ +namespace Grille.BeamNgLib.Collections; + +public interface IKeyed +{ + public string? Key { get; } +} diff --git a/LevelTemplateCreator/Collections/KeyedCollection.cs b/Grille.BeamNGLib/Collections/KeyedCollection.cs similarity index 78% rename from LevelTemplateCreator/Collections/KeyedCollection.cs rename to Grille.BeamNGLib/Collections/KeyedCollection.cs index 5313411..bc02dde 100644 --- a/LevelTemplateCreator/Collections/KeyedCollection.cs +++ b/Grille.BeamNGLib/Collections/KeyedCollection.cs @@ -1,15 +1,9 @@ -using LevelTemplateCreator.Assets; -using System; +using Grille.BeamNgLib.SceneTree.Art; using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -namespace LevelTemplateCreator.Collections; +namespace Grille.BeamNgLib.Collections; -internal class KeyedCollection : ICollection where T : class, IKeyed +public class KeyedCollection : ICollection where T : class, IKeyed { readonly Dictionary _dict; @@ -20,6 +14,8 @@ public KeyedCollection() public int Count => _dict.Count; + public bool IgnoreFalseDuplicates { get; set; } = false; + public bool IsReadOnly => false; public Dictionary.KeyCollection Keys => _dict.Keys; @@ -40,7 +36,7 @@ public void Add(T item) if (TryGetValue(key, out T old)) { - if (old == item) + if (old == item || IgnoreFalseDuplicates) { return; } @@ -98,6 +94,17 @@ public bool Remove(T item) return true; } + public IEnumerable EnumerateItems() where TItem : T + { + foreach (var item in _dict.Values) + { + if (item is TItem) + { + yield return (TItem)item; + } + } + } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); diff --git a/Grille.BeamNGLib/Grille.BeamNgLib.csproj b/Grille.BeamNGLib/Grille.BeamNgLib.csproj new file mode 100644 index 0000000..dc0c366 --- /dev/null +++ b/Grille.BeamNGLib/Grille.BeamNgLib.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + 12 + enable + Grille.BeamNgLib + Grille.BeamNgLib + Grille + https://github.com/Grille/BeamNG_LevelTemplateCreator + True + Copyright (c) 2024 Paul Hirch + README.md + LICENSE + Grille.BeamNG.png + Grille + + + + + + + + + + + + + diff --git a/Grille.BeamNGLib/IO/Binary/TerrainBinary.cs b/Grille.BeamNGLib/IO/Binary/TerrainBinary.cs new file mode 100644 index 0000000..6cc10e2 --- /dev/null +++ b/Grille.BeamNGLib/IO/Binary/TerrainBinary.cs @@ -0,0 +1,39 @@ +namespace Grille.BeamNgLib.IO.Binary; + +public class TerrainBinary +{ + public struct TerrainData + { + public ushort Height; + public byte Material; + + public bool IsHole => Material == byte.MaxValue; + + public void SetHeight(float value, float maxHeight) => Height = TerrainV9Serializer.GetU16Height(value, maxHeight); + public float GetHeight(float maxHeight) => TerrainV9Serializer.GetSingleHeight(Height, maxHeight); + } + + public int Size { get; } + + public TerrainData[] Data { get; } + + public string[] MaterialNames { get; set; } + + public int TotalSize => Size * Size; + + public TerrainBinary(int size) : this(size, Array.Empty()) { } + + public TerrainBinary(int size, string[] materialNames) : this(size, materialNames, new TerrainData[size * size]) { } + + public TerrainBinary(int size, string[] materialNames, TerrainData[] data) + { + Size = size; + Data = data; + MaterialNames = materialNames; + + if (data.Length != TotalSize) + { + throw new ArgumentException($"data.Length must be {TotalSize}", nameof(data)); + } + } +} \ No newline at end of file diff --git a/LevelTemplateCreator/IO/JsonDictSerializer.cs b/Grille.BeamNGLib/IO/JsonDictSerializer.cs similarity index 93% rename from LevelTemplateCreator/IO/JsonDictSerializer.cs rename to Grille.BeamNGLib/IO/JsonDictSerializer.cs index af40d1e..51b1377 100644 --- a/LevelTemplateCreator/IO/JsonDictSerializer.cs +++ b/Grille.BeamNGLib/IO/JsonDictSerializer.cs @@ -1,14 +1,8 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; +using System.Text.Json; -namespace LevelTemplateCreator.IO; +namespace Grille.BeamNgLib.IO; -static class JsonDictSerializer +public class JsonDictSerializer { public const string ArrayClassName = "Template_Array"; public static void Serialize(Stream stream, T value, bool intended = false) where T : IDictionary diff --git a/LevelTemplateCreator/IO/LevelInfoSerializer.cs b/Grille.BeamNGLib/IO/LevelInfoSerializer.cs similarity index 80% rename from LevelTemplateCreator/IO/LevelInfoSerializer.cs rename to Grille.BeamNGLib/IO/LevelInfoSerializer.cs index f6c0ab8..30d915f 100644 --- a/LevelTemplateCreator/IO/LevelInfoSerializer.cs +++ b/Grille.BeamNGLib/IO/LevelInfoSerializer.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.IO; -namespace LevelTemplateCreator.IO; - -static class LevelInfoSerializer +public class LevelInfoSerializer { public static void Serialize(Level level, string path) { diff --git a/Grille.BeamNGLib/IO/Resources/FileResource.cs b/Grille.BeamNGLib/IO/Resources/FileResource.cs new file mode 100644 index 0000000..919f073 --- /dev/null +++ b/Grille.BeamNGLib/IO/Resources/FileResource.cs @@ -0,0 +1,16 @@ +namespace Grille.BeamNgLib.IO.Resources; + +public class FileResource : Resource +{ + public string Path { get; } + + public FileResource(string name, string path, bool isGameResource) : base(name, isGameResource) + { + Path = path; + } + + public override Stream Open() + { + return new FileStream(Path, FileMode.Open); + } +} diff --git a/Grille.BeamNGLib/IO/Resources/GroupResource.cs b/Grille.BeamNGLib/IO/Resources/GroupResource.cs new file mode 100644 index 0000000..7c29c08 --- /dev/null +++ b/Grille.BeamNGLib/IO/Resources/GroupResource.cs @@ -0,0 +1,14 @@ +namespace Grille.BeamNgLib.IO.Resources; + +internal class GroupResource : Resource +{ + public GroupResource(string name, bool isGameResource, Resource[] resources) : base(name, isGameResource) + { + + } + + public override Stream Open() + { + throw new NotImplementedException(); + } +} diff --git a/Grille.BeamNGLib/IO/Resources/PathEvaluator.cs b/Grille.BeamNGLib/IO/Resources/PathEvaluator.cs new file mode 100644 index 0000000..71c857c --- /dev/null +++ b/Grille.BeamNGLib/IO/Resources/PathEvaluator.cs @@ -0,0 +1,38 @@ +namespace Grille.BeamNgLib.IO.Resources; + +public static class PathEvaluator +{ + static public Resource Get(string entry, string gamePath) + { + return Get(entry, gamePath, string.Empty); + } + + static public Resource Get(string entry, string gamePath, string userPath) + { + entry = entry.Replace("\\", "/"); + + string path = entry.StartsWith('/') ? entry.Substring(1) : entry; + return ParseAbsolute(path, gamePath, userPath); + } + + static Resource ParseAbsolute(string entry, string gamePath, string userPath) + { + var split = entry.ToLower().Split([Path.PathSeparator, Path.AltDirectorySeparatorChar]); + + if (split[0] == "levels") + { + var level = split[1]; + var filename = split[split.Length - 1]; + var key = $"beamng.{level}.{filename}"; + var zippath = $"{gamePath}/content/levels/{level}.zip"; + if (File.Exists(zippath)) + { + return new ZipFileResource(key, zippath, entry, true); + } + } + + throw new NotImplementedException(); + } + + +} diff --git a/LevelTemplateCreator/IO/Resources/Resource.cs b/Grille.BeamNGLib/IO/Resources/Resource.cs similarity index 53% rename from LevelTemplateCreator/IO/Resources/Resource.cs rename to Grille.BeamNGLib/IO/Resources/Resource.cs index 396bd6e..b3fe675 100644 --- a/LevelTemplateCreator/IO/Resources/Resource.cs +++ b/Grille.BeamNGLib/IO/Resources/Resource.cs @@ -1,33 +1,29 @@ -using LevelTemplateCreator.Collections; -using LevelTemplateCreator.Properties; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.IO.Resources; - -internal abstract class Resource : IKeyed +using Grille.BeamNgLib.Collections; + +namespace Grille.BeamNgLib.IO.Resources; + +public abstract class Resource : IKeyed { string IKeyed.Key => Name; + public bool IsGameResource { get; } + public string Name { get; } public string DynamicName { get; protected set; } - public Resource(string name) + public Resource(string name, bool isGameResource) { Name = name; DynamicName = name; + IsGameResource = isGameResource; } - public abstract Stream OpenStream(); + public abstract Stream Open(); public void SaveToDirectory(string directory) { - using var stream = OpenStream(); + using var stream = Open(); var dstpath = Path.Combine(directory, DynamicName); using var file = File.OpenWrite(dstpath); stream.CopyTo(file); @@ -35,7 +31,7 @@ public void SaveToDirectory(string directory) public void Save(string path) { - using var src = OpenStream(); + using var src = Open(); using var dst = new FileStream(path, FileMode.Create); src.CopyTo(dst); } diff --git a/Grille.BeamNGLib/IO/Resources/ResourceCollection.cs b/Grille.BeamNGLib/IO/Resources/ResourceCollection.cs new file mode 100644 index 0000000..c0b6640 --- /dev/null +++ b/Grille.BeamNGLib/IO/Resources/ResourceCollection.cs @@ -0,0 +1,21 @@ +using Grille.BeamNgLib.Collections; + +namespace Grille.BeamNgLib.IO.Resources; + +public class ResourceCollection : KeyedCollection +{ + public ResourceCollection() { } + + public ResourceCollection(bool ignoreFalseDuplicates) + { + IgnoreFalseDuplicates = ignoreFalseDuplicates; + } + + public void Save(string path) + { + foreach (var resource in this) + { + resource.SaveToDirectory(path); + } + } +} diff --git a/Grille.BeamNGLib/IO/Resources/StaticPath.cs b/Grille.BeamNGLib/IO/Resources/StaticPath.cs new file mode 100644 index 0000000..3f4c964 --- /dev/null +++ b/Grille.BeamNGLib/IO/Resources/StaticPath.cs @@ -0,0 +1,4 @@ +namespace Grille.BeamNgLib.IO.Resources; +internal class StaticPath +{ +} diff --git a/LevelTemplateCreator/IO/Resources/ZipFileResource.cs b/Grille.BeamNGLib/IO/Resources/ZipFileResource.cs similarity index 73% rename from LevelTemplateCreator/IO/Resources/ZipFileResource.cs rename to Grille.BeamNGLib/IO/Resources/ZipFileResource.cs index 2f6e6a5..12811d5 100644 --- a/LevelTemplateCreator/IO/Resources/ZipFileResource.cs +++ b/Grille.BeamNGLib/IO/Resources/ZipFileResource.cs @@ -1,25 +1,17 @@ -using System; -using System.Collections.Generic; -using System.IO.Compression; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.IO.Resources; -namespace LevelTemplateCreator.IO.Resources; - -internal class ZipFileResource : Resource +public class ZipFileResource : Resource { public string ZipFilePath { get; } public string EntryPath { get; } - public ZipFileResource(string name, string zipFilePath, string path) : base(name) + public ZipFileResource(string name, string zipFilePath, string path, bool isGameResource) : base(name, isGameResource) { ZipFilePath = zipFilePath; EntryPath = path; } - public override Stream OpenStream() + public override Stream Open() { var archive = ZipFileManager.Open(ZipFilePath); var entry = archive.GetEntry(EntryPath); @@ -46,5 +38,5 @@ public override Stream OpenStream() public void Find() { - } + } } diff --git a/Grille.BeamNGLib/IO/TerrainV9Serializer.cs b/Grille.BeamNGLib/IO/TerrainV9Serializer.cs new file mode 100644 index 0000000..7d38cae --- /dev/null +++ b/Grille.BeamNGLib/IO/TerrainV9Serializer.cs @@ -0,0 +1,140 @@ +using System.Text; +using GGL.IO; +using Grille.BeamNgLib.IO.Binary; + +namespace Grille.BeamNgLib.IO; + +public class TerrainV9Serializer +{ + public static TerrainBinary Deserialize(string path, bool ignoreVersion = false) + { + using var stream = new FileStream(path, FileMode.Open); + return Deserialize(stream, ignoreVersion); + } + + public static TerrainBinary Deserialize(Stream stream, bool ignoreVersion = false) + { + using var br = new BinaryViewReader(stream); + + byte version = br.ReadByte(); + if (version != 9 && !ignoreVersion) + { + throw new InvalidDataException($"Unsupported terrain version '{version}'."); + } + + int size = (int)br.ReadUInt32(); + + var terrain = new TerrainBinary(size); + + int sqsize = size * size; + + var data = terrain.Data; + + for (int i = 0; i< sqsize; i++) + { + data[i].Height = br.ReadUInt16(); + } + for (int i = 0; i < sqsize; i++) + { + data[i].Material = br.ReadByte(); + } + + int materialCount = (int)br.ReadUInt32(); + terrain.MaterialNames = new string[materialCount]; + + for (int i = 0; i < materialCount; i++) + { + terrain.MaterialNames[i] = br.ReadString(LengthPrefix.Byte, Encoding.UTF8); + } + + return terrain; + } + + public static void Serialize(TerrainBinary terrain, string path) + { + using var stream = new FileStream(path, FileMode.Create); + Serialize(terrain, stream); + } + + public static void Serialize(TerrainBinary terrain, Stream stream) + { + using var bw = new BinaryViewWriter(stream); + + int size = terrain.Size; + int sqsize = size * size; + + if (terrain.Data.Length != sqsize) + throw new ArgumentException("Data.Length must equal Data.Size^2."); + + bw.WriteByte(9); + bw.WriteUInt32((uint)size); + + var data = terrain.Data; + + for (int i = 0;i < sqsize; i++) + { + bw.WriteUInt16(data[i].Height); + } + for (int i = 0;i < sqsize; i++) + { + bw.WriteByte(data[i].Material); + } + + var names = terrain.MaterialNames; + bw.WriteUInt32((uint)names.Length); + for (int i = 0; i < names.Length; i++) + { + bw.WriteString(names[i], LengthPrefix.Byte, Encoding.UTF8); + } + } + + public static void Serialize(TerrainInfo info, ICollection materials, string path) + { + using var stream = new FileStream(path, FileMode.Create); + Serialize(info, materials, stream); + } + + public static void Serialize(TerrainInfo info, ICollection materials, Stream stream) + { + using var bw = new BinaryViewWriter(stream); + + bw.WriteByte(9); + bw.WriteUInt32((uint)info.Resolution); + + long size = info.Resolution * (long)info.Resolution; + ushort u16height = info.U16Height; + + for (int i = 0; i < size; i++) + { + bw.WriteUInt16(u16height); + } + + bw.Seek(size, SeekOrigin.Current); + + bw.WriteUInt32((uint)materials.Count); + + foreach (var material in materials) + { + bw.WriteString(material, LengthPrefix.Byte, Encoding.UTF8); + } + } + + public static ushort GetU16Height(float height, float maxHeight) + { + float u16max = ushort.MaxValue; + + float u16height = height / maxHeight * u16max; + if (u16height > u16max) + u16height = u16max; + + return (ushort)u16height; + } + + public static float GetSingleHeight(ushort u16height, float maxHeight) + { + float height = u16height; + float u16max = ushort.MaxValue; + + return (height / u16max) * maxHeight; + } +} diff --git a/LevelTemplateCreator/IO/ZipFileManager.cs b/Grille.BeamNGLib/IO/ZipFileManager.cs similarity index 92% rename from LevelTemplateCreator/IO/ZipFileManager.cs rename to Grille.BeamNGLib/IO/ZipFileManager.cs index 2014b0d..d926982 100644 --- a/LevelTemplateCreator/IO/ZipFileManager.cs +++ b/Grille.BeamNGLib/IO/ZipFileManager.cs @@ -1,13 +1,9 @@ -using System; -using System.Collections.Generic; +using Grille.BeamNgLib.Logging; using System.IO.Compression; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace LevelTemplateCreator.IO; +namespace Grille.BeamNgLib.IO; -internal static class ZipFileManager +public static class ZipFileManager { public class ZipArchiveWrapper : IDisposable { diff --git a/Grille.BeamNGLib/Level.cs b/Grille.BeamNGLib/Level.cs new file mode 100644 index 0000000..4b571d4 --- /dev/null +++ b/Grille.BeamNGLib/Level.cs @@ -0,0 +1,24 @@ +using Grille.BeamNgLib.SceneTree.Art; +using Grille.BeamNgLib.SceneTree.Main; + +namespace Grille.BeamNgLib; + +public class Level +{ + public LevelInfo Info { get; } + + public TerrainInfo Terrain { get; } + + public SimGroupRoot Main { get; } + + public ArtGroupRoot Art { get; } + + public Level() + { + Info = new LevelInfo(); + Terrain = new TerrainInfo(); + + Main = new SimGroupRoot(); + Art = new ArtGroupRoot(); + } +} diff --git a/LevelTemplateCreator/LevelInfo.cs b/Grille.BeamNGLib/LevelInfo.cs similarity index 68% rename from LevelTemplateCreator/LevelInfo.cs rename to Grille.BeamNGLib/LevelInfo.cs index 1e9cc55..507294f 100644 --- a/LevelTemplateCreator/LevelInfo.cs +++ b/Grille.BeamNGLib/LevelInfo.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; +namespace Grille.BeamNgLib; -namespace LevelTemplateCreator; - -internal class LevelInfo +public class LevelInfo { public string Title { get; set; } diff --git a/LevelTemplateCreator/Assets/ErrorLogger.cs b/Grille.BeamNGLib/Logging/ErrorLogger.cs similarity index 81% rename from LevelTemplateCreator/Assets/ErrorLogger.cs rename to Grille.BeamNGLib/Logging/ErrorLogger.cs index f7ab953..b52b21f 100644 --- a/LevelTemplateCreator/Assets/ErrorLogger.cs +++ b/Grille.BeamNGLib/Logging/ErrorLogger.cs @@ -1,11 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.Assets; -internal class ErrorLogger +namespace Grille.BeamNgLib.Logging; +public class ErrorLogger { readonly List _errors = new List(); diff --git a/Grille.BeamNGLib/Logging/Logger.cs b/Grille.BeamNGLib/Logging/Logger.cs new file mode 100644 index 0000000..500aebe --- /dev/null +++ b/Grille.BeamNGLib/Logging/Logger.cs @@ -0,0 +1,85 @@ +namespace Grille.BeamNgLib.Logging; + +public enum LoggerColor +{ + Default = ConsoleColor.Gray, + Red = ConsoleColor.Red, +} + +public static class Logger +{ + public static bool EnableConsoleOutput { get; set; } = true; + + static Stream? _stream; + static StreamWriter? _writer; + + public static Stream? OutputStream { get => _stream; set + { + if (_stream == value) + return; + + _stream = value; + + if (_stream == null) + { + _writer = null; + return; + } + + _writer = new StreamWriter(_stream); + } + } + + public static void WriteLine() + { + WriteToStream(); + WriteToConsole(); + } + + public static void WriteLine(string text) + { + WriteToStream(text); + WriteToConsole(text); + } + + public static void WriteLine(string text, LoggerColor color) + { + WriteToStream(text); + WriteToConsole(text, color); + } + + static void WriteToStream() + { + if (_writer == null) + return; + + _writer.WriteLine(); + } + + static void WriteToStream(string text) + { + if (_writer == null) + return; + + _writer.WriteLine(text); + _writer.Flush(); + } + + static void WriteToConsole() + { + if (!EnableConsoleOutput) + return; + + Console.WriteLine(); + } + + static void WriteToConsole(string text, LoggerColor color = LoggerColor.Default) + { + if (!EnableConsoleOutput) + return; + + Console.ForegroundColor = (ConsoleColor)color; + Console.WriteLine(text); + Console.ForegroundColor = (ConsoleColor)LoggerColor.Default; + } +} diff --git a/Grille.BeamNGLib/SceneTree/Art/ArtGroup.cs b/Grille.BeamNGLib/SceneTree/Art/ArtGroup.cs new file mode 100644 index 0000000..091115c --- /dev/null +++ b/Grille.BeamNGLib/SceneTree/Art/ArtGroup.cs @@ -0,0 +1,56 @@ +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.IO; +using Grille.BeamNgLib.IO.Resources; + +namespace Grille.BeamNgLib.SceneTree.Art; + +public class ArtGroup : IKeyed +{ + string IKeyed.Key => Name; + + public string Name { get; } + + public KeyedCollection Children { get; } + + public ResourceCollection Resources { get; } + + public MaterialLibary MaterialItems { get; } + + public ArtGroup(string name) + { + Name = name; + Children = new(); + Resources = new(true); + MaterialItems = new(Resources); + } + + public IEnumerable EnumerateMaterialItems() where T : ArtItem + { + foreach (var item in MaterialItems) + { + if (item is T) + { + yield return (T)item; + } + } + } + + public void SaveTree(string path) + { + Directory.CreateDirectory(path); + + foreach (var item in Children) + { + var childpath = Path.Combine(path, item.Name); + item.SaveTree(childpath); + } + + var materialsPath = Path.Combine(path, MaterialLibary.FileName); + MaterialItems.SerializeItems(materialsPath); + + foreach (var resource in Resources) + { + resource.SaveToDirectory(path); + } + } +} diff --git a/Grille.BeamNGLib/SceneTree/Art/ArtGroupRoot.cs b/Grille.BeamNGLib/SceneTree/Art/ArtGroupRoot.cs new file mode 100644 index 0000000..3ca2124 --- /dev/null +++ b/Grille.BeamNGLib/SceneTree/Art/ArtGroupRoot.cs @@ -0,0 +1,16 @@ +namespace Grille.BeamNgLib.SceneTree.Art; +public class ArtGroupRoot : ArtGroup +{ + public ArtGroup Terrains { get; } + + public ArtGroup Groundcover { get; } + + public ArtGroupRoot() : base("art") + { + Terrains = new("terrains"); + Groundcover = new("groundcover"); + + Children.Add(Terrains); + Children.Add(Groundcover); + } +} diff --git a/Grille.BeamNGLib/SceneTree/Art/ArtItem.cs b/Grille.BeamNGLib/SceneTree/Art/ArtItem.cs new file mode 100644 index 0000000..11d7b9e --- /dev/null +++ b/Grille.BeamNGLib/SceneTree/Art/ArtItem.cs @@ -0,0 +1,8 @@ + +namespace Grille.BeamNgLib.SceneTree.Art; +public class ArtItem : JsonDictWrapper +{ + public ArtItem(JsonDict dict) : base(dict) + { + } +} diff --git a/LevelTemplateCreator/SceneTree/Art/ForestItemData.cs b/Grille.BeamNGLib/SceneTree/Art/ForestItemData.cs similarity index 51% rename from LevelTemplateCreator/SceneTree/Art/ForestItemData.cs rename to Grille.BeamNGLib/SceneTree/Art/ForestItemData.cs index d250ade..fcb6001 100644 --- a/LevelTemplateCreator/SceneTree/Art/ForestItemData.cs +++ b/Grille.BeamNGLib/SceneTree/Art/ForestItemData.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Art; -namespace LevelTemplateCreator.SceneTree.Art; - -internal class ForestItemData : JsonDictWrapper +public sealed class ForestItemData : JsonDictWrapper { public const string ClassName = "TSForestItemData"; diff --git a/Grille.BeamNGLib/SceneTree/Art/Material.cs b/Grille.BeamNGLib/SceneTree/Art/Material.cs new file mode 100644 index 0000000..b145d5c --- /dev/null +++ b/Grille.BeamNGLib/SceneTree/Art/Material.cs @@ -0,0 +1,8 @@ +namespace Grille.BeamNgLib.SceneTree.Art; + +public abstract class Material : ArtItem +{ + protected Material(JsonDict dict) : base(dict) { } + + public abstract IEnumerable> EnumerateTexturePaths(); +} diff --git a/Grille.BeamNGLib/SceneTree/Art/MaterialLibary.cs b/Grille.BeamNGLib/SceneTree/Art/MaterialLibary.cs new file mode 100644 index 0000000..b64f006 --- /dev/null +++ b/Grille.BeamNGLib/SceneTree/Art/MaterialLibary.cs @@ -0,0 +1,45 @@ +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.IO; +using Grille.BeamNgLib.IO.Resources; + +namespace Grille.BeamNgLib.SceneTree.Art; + +public class MaterialLibary : KeyedCollection +{ + public const string FileName = "main.materials.json"; + + public ResourceCollection Resources { get; } + + public MaterialLibary(ResourceCollection resources) + { + Resources = resources; + } + + public string[] GetMaterialNames() + { + List names = new List(); + foreach (var material in EnumerateItems()) + { + names.Add(material.Name.Value); + } + return names.ToArray(); + } + + public void SerializeItems(string path) + { + using var stream = new FileStream(path, FileMode.Create); + SerializeItems(stream); + } + + public void SerializeItems(Stream stream) + { + var dict = new JsonDict(); + + foreach (var item in this) + { + dict[item.Name.Value] = item.Dict; + } + + JsonDictSerializer.Serialize(stream, dict, true); + } +} diff --git a/LevelTemplateCreator/SceneTree/Art/MaterialNode.cs b/Grille.BeamNGLib/SceneTree/Art/MaterialNode.cs similarity index 54% rename from LevelTemplateCreator/SceneTree/Art/MaterialNode.cs rename to Grille.BeamNGLib/SceneTree/Art/MaterialNode.cs index fdcd61b..6ff0465 100644 --- a/LevelTemplateCreator/SceneTree/Art/MaterialNode.cs +++ b/Grille.BeamNGLib/SceneTree/Art/MaterialNode.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Art; -namespace LevelTemplateCreator.SceneTree.Art; - -internal class MaterialNode +public class MaterialNode { public string Name { get; } diff --git a/LevelTemplateCreator/SceneTree/Art/ObjectMaterial.cs b/Grille.BeamNGLib/SceneTree/Art/ObjectMaterial.cs similarity index 57% rename from LevelTemplateCreator/SceneTree/Art/ObjectMaterial.cs rename to Grille.BeamNGLib/SceneTree/Art/ObjectMaterial.cs index f0d122e..949e857 100644 --- a/LevelTemplateCreator/SceneTree/Art/ObjectMaterial.cs +++ b/Grille.BeamNGLib/SceneTree/Art/ObjectMaterial.cs @@ -1,26 +1,19 @@ -using LevelTemplateCreator.Assets; -using LevelTemplateCreator.IO.Resources; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.SceneTree.Art; - -internal class ObjectMaterial : Material +using System.Collections.ObjectModel; + +namespace Grille.BeamNgLib.SceneTree.Art; + +public class ObjectMaterial : Material { public const string ClassName = "Material"; public JsonDictProperty Version { get; } - public ReadOnlyCollection Stages { get; } + public ReadOnlyCollection Stages { get; } - public ObjectPbrMaterialStage Stage0 { get; } - public ObjectPbrMaterialStage Stage1 { get; } - public ObjectPbrMaterialStage Stage2 { get; } - public ObjectPbrMaterialStage Stage3 { get; } + public ObjectMaterialStage Stage0 { get; } + public ObjectMaterialStage Stage1 { get; } + public ObjectMaterialStage Stage2 { get; } + public ObjectMaterialStage Stage3 { get; } public ObjectMaterial(JsonDict dict) : base(dict) { @@ -36,7 +29,7 @@ public ObjectMaterial(JsonDict dict) : base(dict) Stages = new([Stage0, Stage1, Stage2, Stage3]); } - public override void ResolveTexturePaths(MaterialLibary libary, AssetInfo info) + public override IEnumerable> EnumerateTexturePaths() { foreach (var stage in Stages) { @@ -44,23 +37,14 @@ public override void ResolveTexturePaths(MaterialLibary libary, AssetInfo info) { if (!map.Exists) continue; - var key = libary.Textures.RegisterRelative(map.Value, info); - map.Value = Path.Combine(libary.TexturesPath, key); + + yield return map; } } } - - public override ObjectMaterial Copy() - { - var clone = new JsonDict(Dict); - var stages = new JsonDict[4] { new(Stage0.Dict), new(Stage1.Dict), new(Stage2.Dict), new(Stage3.Dict) }; - clone["Stages"] = stages; - - return new ObjectMaterial(clone); - } } -class ObjectPbrMaterialStage : JsonDictWrapper +public class ObjectMaterialStage : JsonDictWrapper { public JsonDictProperty AmbientOcclusionMap { get; } @@ -78,7 +62,7 @@ class ObjectPbrMaterialStage : JsonDictWrapper public ReadOnlyCollection> Maps { get; } - public ObjectPbrMaterialStage(JsonDict dict) : base(dict) + public ObjectMaterialStage(JsonDict dict) : base(dict) { AmbientOcclusionMap = new(this, "ambientOcclusionMap"); BaseColorMap = new(this, "baseColorMap"); diff --git a/LevelTemplateCreator/SceneTree/Art/TerrainMaterial.cs b/Grille.BeamNGLib/SceneTree/Art/TerrainMaterial.cs similarity index 84% rename from LevelTemplateCreator/SceneTree/Art/TerrainMaterial.cs rename to Grille.BeamNGLib/SceneTree/Art/TerrainMaterial.cs index 11a7499..5cc9119 100644 --- a/LevelTemplateCreator/SceneTree/Art/TerrainMaterial.cs +++ b/Grille.BeamNGLib/SceneTree/Art/TerrainMaterial.cs @@ -1,15 +1,7 @@ -using LevelTemplateCreator.Assets; -using LevelTemplateCreator.IO.Resources; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Numerics; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.SceneTree.Art; -internal class TerrainMaterial : Material +using System.Collections.ObjectModel; + +namespace Grille.BeamNgLib.SceneTree.Art; +public class TerrainMaterial : Material { public const string ClassName = "TerrainMaterial"; @@ -86,25 +78,20 @@ public void CreatePersistentId() Name.Value = $"{InternalName}_{PersistentId}"; } - public override void ResolveTexturePaths(MaterialLibary libary, AssetInfo source) + public override IEnumerable> EnumerateTexturePaths() { - foreach (var level in Levels) + foreach(var level in Levels) { - if (level.IsTextureEmpty) + var texture = level.Texture; + if (!texture.Exists) continue; - var key = libary.Textures.RegisterRelative(level.Texture.Value, source); - level.Texture.Value = Path.Combine(libary.TexturesPath, key); - } - } - public override TerrainMaterial Copy() - { - var copy = new JsonDict(Dict); - return new TerrainMaterial(copy); + yield return level.Texture; + } } } -internal class TerrainMaterialDistances +public class TerrainMaterialDistances { public string Prefix { get; } public TerrainMaterial Owner { get; } @@ -136,7 +123,7 @@ public TerrainMaterialDistances(TerrainMaterial owner, string prefix, float[] di public int EndFadeOut { get => (int)Distances.Value[3]; set => Distances.Value[3] = value; } } -internal class TerrainMaterialTexture +public class TerrainMaterialTexture { public string Prefix { get; } public TerrainMaterial Owner { get; } @@ -156,7 +143,7 @@ public TerrainMaterialTexture(TerrainMaterial owner, string prefix) } } -internal class TerrainMaterialTextureLayer +public class TerrainMaterialTextureLayer { public string Prefix { get; } public TerrainMaterial Owner { get; } diff --git a/LevelTemplateCreator/SceneTree/Art/TerrainMaterialTextureSet.cs b/Grille.BeamNGLib/SceneTree/Art/TerrainMaterialTextureSet.cs similarity index 72% rename from LevelTemplateCreator/SceneTree/Art/TerrainMaterialTextureSet.cs rename to Grille.BeamNGLib/SceneTree/Art/TerrainMaterialTextureSet.cs index 6b0742c..173a5d1 100644 --- a/LevelTemplateCreator/SceneTree/Art/TerrainMaterialTextureSet.cs +++ b/Grille.BeamNGLib/SceneTree/Art/TerrainMaterialTextureSet.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Numerics; +namespace Grille.BeamNgLib.SceneTree.Art; -namespace LevelTemplateCreator.SceneTree.Art; - -internal class TerrainMaterialTextureSet : JsonDictWrapper +public class TerrainMaterialTextureSet : ArtItem { public JsonDictProperty BaseTexSize { get; } public JsonDictProperty DetailTexSize { get; } diff --git a/LevelTemplateCreator/SceneTree/JsonDictProperty.cs b/Grille.BeamNGLib/SceneTree/JsonDictProperty.cs similarity index 91% rename from LevelTemplateCreator/SceneTree/JsonDictProperty.cs rename to Grille.BeamNGLib/SceneTree/JsonDictProperty.cs index c175940..4ca4391 100644 --- a/LevelTemplateCreator/SceneTree/JsonDictProperty.cs +++ b/Grille.BeamNGLib/SceneTree/JsonDictProperty.cs @@ -1,20 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; +using System.Runtime.CompilerServices; -namespace LevelTemplateCreator.SceneTree; +namespace Grille.BeamNgLib.SceneTree; struct JsonDictProperty { public readonly JsonDictWrapper Owner; public readonly string Key; - public JsonDictProperty(JsonDictWrapper owner, string key) { + public JsonDictProperty(JsonDictWrapper owner, string key) + { Owner = owner; Key = key; } @@ -72,7 +66,7 @@ public float Single() } } -class JsonDictProperty where T : notnull +public class JsonDictProperty where T : notnull { enum PropertyType { @@ -90,7 +84,7 @@ enum PropertyType public T? DefaultValue { get; } - public T Value { get => Get();set => Set(value); } + public T Value { get => Get(); set => Set(value); } public JsonDictProperty(JsonDictWrapper owner, string key) { @@ -105,7 +99,7 @@ public JsonDictProperty(JsonDictWrapper owner, string key) _type = PropertyType.Vec2; else if (t == typeof(Vector3)) _type = PropertyType.Vec3; - else + else _type = PropertyType.Object; } diff --git a/LevelTemplateCreator/SceneTree/JsonDictWrapper.cs b/Grille.BeamNGLib/SceneTree/JsonDictWrapper.cs similarity index 69% rename from LevelTemplateCreator/SceneTree/JsonDictWrapper.cs rename to Grille.BeamNGLib/SceneTree/JsonDictWrapper.cs index 248c431..f14987f 100644 --- a/LevelTemplateCreator/SceneTree/JsonDictWrapper.cs +++ b/Grille.BeamNGLib/SceneTree/JsonDictWrapper.cs @@ -1,18 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using LevelTemplateCreator.Collections; -using LevelTemplateCreator.IO; +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.IO; -using LevelTemplateCreator.SceneTree.Main; +namespace Grille.BeamNgLib.SceneTree; -namespace LevelTemplateCreator.SceneTree; - -internal class JsonDictWrapper : IKeyed +public abstract class JsonDictWrapper : IKeyed { public JsonDict Dict { get; } @@ -51,7 +42,8 @@ public void Deserialize(Stream stream) public bool TryGetValue(string key, out T value) { - if (Dict.TryGetValue(key, out var obj)){ + if (Dict.TryGetValue(key, out var obj)) + { value = (T)obj; return true; } @@ -77,17 +69,6 @@ public void TryPopValue(string key, out T value, T defaultValue) } } - public virtual void CopyTo(JsonDictWrapper target) - { - if (target.Class.Exists && target.Class.Value != Class.Value) - throw new ArgumentException($"Canot copy '{Class}' to '{target.Class}'"); - - foreach (var pair in Dict) - { - target[pair.Key] = pair.Value; - } - } - public void ApplyNamespace(string @namespace) { if (!string.IsNullOrEmpty(@namespace)) @@ -108,10 +89,15 @@ public virtual void ApplyPrefix(string prefix) } } - public virtual JsonDictWrapper Copy() + public JsonDict CopyDict() { - var dict = new JsonDict(Dict); - return new JsonDictWrapper(dict); + var dict = new JsonDict(); + CopyDict(Dict, dict); + return dict; } + public static void CopyDict(JsonDict src, JsonDict dst) + { + + } } \ No newline at end of file diff --git a/LevelTemplateCreator/SceneTree/Main/GroundCover.cs b/Grille.BeamNGLib/SceneTree/Main/GroundCover.cs similarity index 56% rename from LevelTemplateCreator/SceneTree/Main/GroundCover.cs rename to Grille.BeamNGLib/SceneTree/Main/GroundCover.cs index 0915bf9..ee1a97e 100644 --- a/LevelTemplateCreator/SceneTree/Main/GroundCover.cs +++ b/Grille.BeamNGLib/SceneTree/Main/GroundCover.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class GroundCover : SimItem +public class GroundCover : SimItem { public const string ClassName = "GroundCover"; @@ -21,17 +15,6 @@ public GroundCover(JsonDict dict) : base(dict) Types = new(this, "Types"); } - public override GroundCover Copy() - { - if (Types.Exists) - { - throw new Exception(); - } - - var dict = new JsonDict(Dict); - return new GroundCover(dict); - } - public void AddInstance(GroundCoverInstance instance) { diff --git a/LevelTemplateCreator/SceneTree/Main/GroundCoverInstance.cs b/Grille.BeamNGLib/SceneTree/Main/GroundCoverInstance.cs similarity index 73% rename from LevelTemplateCreator/SceneTree/Main/GroundCoverInstance.cs rename to Grille.BeamNGLib/SceneTree/Main/GroundCoverInstance.cs index 1c0e98c..1025ee2 100644 --- a/LevelTemplateCreator/SceneTree/Main/GroundCoverInstance.cs +++ b/Grille.BeamNGLib/SceneTree/Main/GroundCoverInstance.cs @@ -1,13 +1,6 @@ -using LevelTemplateCreator.SceneTree.Art; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class GroundCoverInstance : JsonDictWrapper +public class GroundCoverInstance : JsonDictWrapper { public const string ClassName = "GroundCover_Instance"; @@ -38,7 +31,7 @@ static GroundCoverInstance[] PopFromObject(JsonDictWrapper obj) for (int i = 0; i < array.Value.Length; i++) { var dict = array.Value[i]; - if (dict.Count == 0) + if (dict.Count == 0) continue; var instance = new GroundCoverInstance(dict); @@ -51,12 +44,6 @@ static GroundCoverInstance[] PopFromObject(JsonDictWrapper obj) return result.ToArray(); } - public override GroundCoverInstance Copy() - { - var dict = new JsonDict(Dict); - return new GroundCoverInstance(dict); - } - public override void ApplyPrefix(string prefix) { base.ApplyPrefix(prefix); diff --git a/LevelTemplateCreator/SceneTree/Main/SimGroup.cs b/Grille.BeamNGLib/SceneTree/Main/SimGroup.cs similarity index 66% rename from LevelTemplateCreator/SceneTree/Main/SimGroup.cs rename to Grille.BeamNGLib/SceneTree/Main/SimGroup.cs index b01e323..4f0a3be 100644 --- a/LevelTemplateCreator/SceneTree/Main/SimGroup.cs +++ b/Grille.BeamNGLib/SceneTree/Main/SimGroup.cs @@ -1,16 +1,9 @@ -using System; -using System.Collections; -using System.Collections.Generic; +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.SceneTree.Art; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -using LevelTemplateCreator.Collections; - -namespace LevelTemplateCreator.SceneTree.Main; - -internal class SimGroup : SimItem +public class SimGroup : SimItem { public bool IsMain { get; set; } = false; @@ -46,6 +39,17 @@ public void SerializeItems(Stream stream) } } + public IEnumerable EnumerateItems() where T : SimItem + { + foreach (var item in Items) + { + if (item is T) + { + yield return (T)item; + } + } + } + public const string FileName = "items.level.json"; public void SaveTree(string path) @@ -57,19 +61,11 @@ public void SaveTree(string path) var filePath = Path.Combine(path, FileName); SerializeItems(filePath); - foreach (var item in Items) + foreach (var item in EnumerateItems()) { - if (item is SimGroup) - { - var childPath = Path.Combine(path, item.Name.Value); - Directory.CreateDirectory(childPath); - ((SimGroup)item).SaveTree(childPath); - } + var childPath = Path.Combine(path, item.Name.Value); + Directory.CreateDirectory(childPath); + item.SaveTree(childPath); } } - - public override void CopyTo(JsonDictWrapper target) - { - throw new NotSupportedException(); - } } diff --git a/LevelTemplateCreator/SceneTree/Main/SimGroupLevelObjects.cs b/Grille.BeamNGLib/SceneTree/Main/SimGroupLevelObjects.cs similarity index 74% rename from LevelTemplateCreator/SceneTree/Main/SimGroupLevelObjects.cs rename to Grille.BeamNGLib/SceneTree/Main/SimGroupLevelObjects.cs index a3a0d25..6ffec1b 100644 --- a/LevelTemplateCreator/SceneTree/Main/SimGroupLevelObjects.cs +++ b/Grille.BeamNGLib/SceneTree/Main/SimGroupLevelObjects.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class SimGroupLevelObjects : SimGroup +public class SimGroupLevelObjects : SimGroup { public SimGroup Cloud { get; } diff --git a/LevelTemplateCreator/SceneTree/Main/SimGroupMissionGroup.cs b/Grille.BeamNGLib/SceneTree/Main/SimGroupMissionGroup.cs similarity index 61% rename from LevelTemplateCreator/SceneTree/Main/SimGroupMissionGroup.cs rename to Grille.BeamNGLib/SceneTree/Main/SimGroupMissionGroup.cs index 4fd4501..7827087 100644 --- a/LevelTemplateCreator/SceneTree/Main/SimGroupMissionGroup.cs +++ b/Grille.BeamNGLib/SceneTree/Main/SimGroupMissionGroup.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class SimGroupMissionGroup : SimGroup +public class SimGroupMissionGroup : SimGroup { public SimGroupLevelObjects LevelObject { get; } diff --git a/LevelTemplateCreator/SceneTree/Main/SimGroupRoot.cs b/Grille.BeamNGLib/SceneTree/Main/SimGroupRoot.cs similarity index 51% rename from LevelTemplateCreator/SceneTree/Main/SimGroupRoot.cs rename to Grille.BeamNGLib/SceneTree/Main/SimGroupRoot.cs index 417ef69..39315e8 100644 --- a/LevelTemplateCreator/SceneTree/Main/SimGroupRoot.cs +++ b/Grille.BeamNGLib/SceneTree/Main/SimGroupRoot.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class SimGroupRoot : SimGroup +public class SimGroupRoot : SimGroup { public SimGroupMissionGroup MissionGroup { get; } diff --git a/LevelTemplateCreator/SceneTree/Main/SimItem.cs b/Grille.BeamNGLib/SceneTree/Main/SimItem.cs similarity index 66% rename from LevelTemplateCreator/SceneTree/Main/SimItem.cs rename to Grille.BeamNGLib/SceneTree/Main/SimItem.cs index 8e1732c..fb6caf7 100644 --- a/LevelTemplateCreator/SceneTree/Main/SimItem.cs +++ b/Grille.BeamNGLib/SceneTree/Main/SimItem.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class SimItem : JsonDictWrapper +public class SimItem : JsonDictWrapper { public JsonDictProperty Position { get; } diff --git a/LevelTemplateCreator/SceneTree/Main/SpawnSphere.cs b/Grille.BeamNGLib/SceneTree/Main/SpawnSphere.cs similarity index 82% rename from LevelTemplateCreator/SceneTree/Main/SpawnSphere.cs rename to Grille.BeamNGLib/SceneTree/Main/SpawnSphere.cs index 2570213..251814f 100644 --- a/LevelTemplateCreator/SceneTree/Main/SpawnSphere.cs +++ b/Grille.BeamNGLib/SceneTree/Main/SpawnSphere.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class SpawnSphere : SimItem +public class SpawnSphere : SimItem { public JsonDictProperty DataBlock { get; } diff --git a/LevelTemplateCreator/SceneTree/Main/TerrainBlock.cs b/Grille.BeamNGLib/SceneTree/Main/TerrainBlock.cs similarity index 82% rename from LevelTemplateCreator/SceneTree/Main/TerrainBlock.cs rename to Grille.BeamNGLib/SceneTree/Main/TerrainBlock.cs index ba3a925..cac6d60 100644 --- a/LevelTemplateCreator/SceneTree/Main/TerrainBlock.cs +++ b/Grille.BeamNGLib/SceneTree/Main/TerrainBlock.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Grille.BeamNgLib.SceneTree.Main; -namespace LevelTemplateCreator.SceneTree.Main; - -internal class TerrainBlock : SimItem +public class TerrainBlock : SimItem { public JsonDictProperty MaterialTextureSet { get; } public JsonDictProperty TerrainFile { get; } diff --git a/LevelTemplateCreator/TerrainInfo.cs b/Grille.BeamNGLib/TerrainInfo.cs similarity index 82% rename from LevelTemplateCreator/TerrainInfo.cs rename to Grille.BeamNGLib/TerrainInfo.cs index f79dd03..78a1efb 100644 --- a/LevelTemplateCreator/TerrainInfo.cs +++ b/Grille.BeamNGLib/TerrainInfo.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Grille.BeamNgLib.IO; -namespace LevelTemplateCreator; +namespace Grille.BeamNgLib; -internal class TerrainInfo +public class TerrainInfo { private int resolution; @@ -55,4 +51,6 @@ public float WorldSize public float MaxHeight { get; set; } public float Height { get; set; } + + public ushort U16Height => TerrainV9Serializer.GetU16Height(Height, MaxHeight); } diff --git a/Grille.BeamNGLib/usings.cs b/Grille.BeamNGLib/usings.cs new file mode 100644 index 0000000..2c7b819 --- /dev/null +++ b/Grille.BeamNGLib/usings.cs @@ -0,0 +1,6 @@ +global using System; +global using System.Collections.Generic; +global using System.IO; +global using System.Numerics; + +global using JsonDict = System.Collections.Generic.Dictionary; \ No newline at end of file diff --git a/Grille.BeamNGLib_Tests/Grille.BeamNgLib_Tests.csproj b/Grille.BeamNGLib_Tests/Grille.BeamNgLib_Tests.csproj new file mode 100644 index 0000000..2755523 --- /dev/null +++ b/Grille.BeamNGLib_Tests/Grille.BeamNgLib_Tests.csproj @@ -0,0 +1,18 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + diff --git a/Grille.BeamNGLib_Tests/Program.cs b/Grille.BeamNGLib_Tests/Program.cs new file mode 100644 index 0000000..a544ddc --- /dev/null +++ b/Grille.BeamNGLib_Tests/Program.cs @@ -0,0 +1,13 @@ +namespace Grille.BeamNgLib_Tests; + +internal class Program +{ + static void Main(string[] args) + { + ExecuteImmediately = true; + + Terrain.Run(); + + RunTestsSynchronously(); + } +} diff --git a/Grille.BeamNGLib_Tests/Terrain.cs b/Grille.BeamNGLib_Tests/Terrain.cs new file mode 100644 index 0000000..e6bf0d1 --- /dev/null +++ b/Grille.BeamNGLib_Tests/Terrain.cs @@ -0,0 +1,72 @@ +using Grille.BeamNgLib.IO.Binary; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Grille.BeamNgLib.IO; +using Grille.BeamNgLib; +using System.IO.Enumeration; + +namespace Grille.BeamNgLib_Tests; + +static class Terrain +{ + const string FileName = "terrain.ter"; + + public static void Run() + { + Section("Terrain"); + + Test("Terrain", TestTerrainFromInfo); + Test("Terrain", TestTerrain); + } + + static void TestTerrainFromInfo() + { + var names = new string[] + { + "Material0", + "Material1", + }; + + float maxHeight = 512; + float height = 10; + var info = new TerrainInfo() { Height = height, MaxHeight = maxHeight }; + ushort u16height = info.U16Height; + + TerrainV9Serializer.Serialize(info, names, FileName); + + var result = TerrainV9Serializer.Deserialize(FileName); + + AssertIsEqual((int)height, (int)(result.Data[0].GetHeight(maxHeight) + 0.5f)); + + for (int i = 0;i(int size, T value) + { + var array = new T[size]; + for (int i = 0; i < array.Length; i++) { array[i] = value; } + return array; + } +} diff --git a/Grille.BeamNGLib_Tests/usings.cs b/Grille.BeamNGLib_Tests/usings.cs new file mode 100644 index 0000000..49c10e5 --- /dev/null +++ b/Grille.BeamNGLib_Tests/usings.cs @@ -0,0 +1,5 @@ +global using Grille.ConsoleTestLib; +global using static Grille.ConsoleTestLib.GlobalTestSystem; +global using static Grille.ConsoleTestLib.TestResult; +global using static Grille.ConsoleTestLib.UsingSyntaxAsserts; +global using static Grille.BeamNgLib_Tests.Utils; \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..32cdd27 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Paul Hirch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/LevelTemplateCreator.sln b/LevelTemplateCreator.sln index 5065e92..70c6670 100644 --- a/LevelTemplateCreator.sln +++ b/LevelTemplateCreator.sln @@ -3,13 +3,20 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34525.116 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LevelTemplateCreator", "LevelTemplateCreator/LevelTemplateCreator.csproj", "{C31B145C-37AF-46FA-B194-BB982020A461}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LevelTemplateCreator", "LevelTemplateCreator\LevelTemplateCreator.csproj", "{C31B145C-37AF-46FA-B194-BB982020A461}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C3C03C73-5671-4D98-A299-32AC586BBA17}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + .gitignore = .gitignore + LICENSE = LICENSE + README.md = README.md EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grille.BeamNgLib", "Grille.BeamNGLib\Grille.BeamNgLib.csproj", "{71707660-F679-4412-AC29-0358B3D29738}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grille.BeamNgLib_Tests", "Grille.BeamNGLib_Tests\Grille.BeamNgLib_Tests.csproj", "{5435185E-3DDF-4D35-BF74-E79A8ECD649C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,6 +27,14 @@ Global {C31B145C-37AF-46FA-B194-BB982020A461}.Debug|Any CPU.Build.0 = Debug|Any CPU {C31B145C-37AF-46FA-B194-BB982020A461}.Release|Any CPU.ActiveCfg = Release|Any CPU {C31B145C-37AF-46FA-B194-BB982020A461}.Release|Any CPU.Build.0 = Release|Any CPU + {71707660-F679-4412-AC29-0358B3D29738}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {71707660-F679-4412-AC29-0358B3D29738}.Debug|Any CPU.Build.0 = Debug|Any CPU + {71707660-F679-4412-AC29-0358B3D29738}.Release|Any CPU.ActiveCfg = Release|Any CPU + {71707660-F679-4412-AC29-0358B3D29738}.Release|Any CPU.Build.0 = Release|Any CPU + {5435185E-3DDF-4D35-BF74-E79A8ECD649C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5435185E-3DDF-4D35-BF74-E79A8ECD649C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5435185E-3DDF-4D35-BF74-E79A8ECD649C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5435185E-3DDF-4D35-BF74-E79A8ECD649C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/LevelTemplateCreator/Assets/Asset.cs b/LevelTemplateCreator/Assets/Asset.cs index 3ec9cf9..93eef11 100644 --- a/LevelTemplateCreator/Assets/Asset.cs +++ b/LevelTemplateCreator/Assets/Asset.cs @@ -1,6 +1,7 @@ -using LevelTemplateCreator.Collections; +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.SceneTree; using LevelTemplateCreator.IO.Resources; -using LevelTemplateCreator.SceneTree; +using LevelTemplateCreator.Properties; using System; using System.Collections.Generic; using System.Diagnostics; @@ -9,13 +10,12 @@ using System.Text; using System.Threading.Tasks; using System.Xml.Linq; -using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace LevelTemplateCreator.Assets; -abstract class Asset : IKeyed +public abstract class Asset : IKeyed { - string IKeyed.Key => Object.Name.Value; + public string Key { get; } public string DisplayName { get; set; } = string.Empty; @@ -29,24 +29,29 @@ abstract class Asset : IKeyed public string Namespace { get; } - public AssetInfo Info { get; } + public AssetSource Info { get; } - public JsonDictWrapper Object { get; } + public string Class { get; } - public Asset(JsonDictWrapper obj, AssetInfo info) + public Asset(JsonDictWrapper obj, AssetSource info) { + if (!obj.Name.Exists) + { + throw new ArgumentException("Object must have a name.", nameof(obj)); + } Info = info; - Object = obj; SourceFile = info.SourceFile; Namespace = info.Namespace; obj.ApplyNamespace(Namespace); + Key = obj.Name.Value; if (obj.TryPopValue("preview", out string path)) { try { - using var stream = ResourceManager.Parse(path, SourceFile).OpenStream(); + var resource = PathExpressionEvaluator.Get(path, info); + using var stream = resource.Open(); var bitmap = new Bitmap(stream); Preview = bitmap; } @@ -66,30 +71,33 @@ public Asset(JsonDictWrapper obj, AssetInfo info) } else if (obj.Name.Exists) { - DisplayName = Object.Name.Value; + DisplayName = obj.Name.Value; } if (obj.TryPopValue("description", out string desc)) { Description = desc; } - } - public virtual JsonDictWrapper GetCopy() - { - return Object.Copy(); + if (obj.TryGetValue("class", out string @class)){ + Class = @class; + } + else + { + Class = string.Empty; + } + } } -abstract class Asset : Asset where T : JsonDictWrapper +public abstract class Asset : Asset where T : JsonDictWrapper { - public new T Object => (T)base.Object; - - public Asset(T obj, AssetInfo info) : base(obj, info) { } + public T Object { get; } - public override T GetCopy() - { - return (T)Object.Copy(); + public Asset(T obj, AssetSource info) : base(obj, info) { + Object = obj; } + + public abstract T GetCopy(); } diff --git a/LevelTemplateCreator/Assets/AssetCollection.cs b/LevelTemplateCreator/Assets/AssetCollection.cs index b43fe39..6560d39 100644 --- a/LevelTemplateCreator/Assets/AssetCollection.cs +++ b/LevelTemplateCreator/Assets/AssetCollection.cs @@ -1,4 +1,4 @@ -using LevelTemplateCreator.Collections; +using Grille.BeamNgLib.Collections; using System; using System.Collections; using System.Collections.Generic; @@ -8,4 +8,4 @@ namespace LevelTemplateCreator.Assets; -internal class AssetCollection : KeyedCollection where T : Asset { } +public class AssetCollection : KeyedCollection where T : Asset { } diff --git a/LevelTemplateCreator/Assets/AssetLibary.cs b/LevelTemplateCreator/Assets/AssetLibary.cs index 0b543b6..03d345d 100644 --- a/LevelTemplateCreator/Assets/AssetLibary.cs +++ b/LevelTemplateCreator/Assets/AssetLibary.cs @@ -1,13 +1,10 @@ -using LevelTemplateCreator.Collections; -using LevelTemplateCreator.IO; -using LevelTemplateCreator.IO.Resources; -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Art; -using LevelTemplateCreator.SceneTree.Main; +using Grille.BeamNgLib.Logging; +using Grille.BeamNgLib.SceneTree.Main; + namespace LevelTemplateCreator.Assets; -internal class AssetLibary +public class AssetLibary { public AssetCollection LevelPresets { get; } diff --git a/LevelTemplateCreator/Assets/AssetLibaryContent.cs b/LevelTemplateCreator/Assets/AssetLibaryContent.cs index c5f4ac8..0ac37ec 100644 --- a/LevelTemplateCreator/Assets/AssetLibaryContent.cs +++ b/LevelTemplateCreator/Assets/AssetLibaryContent.cs @@ -1,5 +1,5 @@ -using LevelTemplateCreator.Collections; -using LevelTemplateCreator.SceneTree.Main; +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.SceneTree.Main; using System; using System.Collections.Generic; using System.Linq; @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace LevelTemplateCreator.Assets; -internal class AssetLibaryContent : AssetLibary +public class AssetLibaryContent : AssetLibary { public List GroundCoverObjects { get; } @@ -83,7 +83,6 @@ void CreateGroundCoverObjects() builders.Add(builder); } - foreach (var item in GroundCoverInstances) { var parent = item.Parent.Value; diff --git a/LevelTemplateCreator/Assets/AssetLibaryLoader.cs b/LevelTemplateCreator/Assets/AssetLibaryLoader.cs index d71fd24..34de95f 100644 --- a/LevelTemplateCreator/Assets/AssetLibaryLoader.cs +++ b/LevelTemplateCreator/Assets/AssetLibaryLoader.cs @@ -1,15 +1,17 @@ -using LevelTemplateCreator.IO; +using Grille.BeamNgLib.IO; using LevelTemplateCreator.IO.Resources; -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Art; -using LevelTemplateCreator.SceneTree.Main; +using LevelTemplateCreator.Properties; +using Grille.BeamNgLib.SceneTree; +using Grille.BeamNgLib.SceneTree.Art; +using Grille.BeamNgLib.SceneTree.Main; using System.Linq; using System.Text; using System.Xml.Linq; +using Grille.BeamNgLib.Logging; namespace LevelTemplateCreator.Assets; -internal class AssetLibaryLoader +public class AssetLibaryLoader { public record class Error(string File, Exception Exception) { @@ -57,8 +59,6 @@ public AssetLibaryLoader(AssetLibary libary) { Libary = libary; Errors = new ErrorLogger(); - - } void LogException(Exception e) @@ -185,7 +185,7 @@ void ParseObject(JsonDict dict) void ParseObject(JsonDict dict, string className) { - var createInfo = new AssetInfo(_currentFile, _currentNamespace); + var createInfo = new AssetSource(_currentFile, _currentNamespace); switch (className) { @@ -206,7 +206,7 @@ void ParseObject(JsonDict dict, string className) } case LevelObjectsAsset.ClassName: { - var obj = new JsonDictWrapper(dict); + var obj = new SimItem(dict); var asset = new LevelObjectsAsset(obj, createInfo); Libary.LevelPresets.Add(asset); break; @@ -337,8 +337,8 @@ void Include(string path) { var filename = Path.GetFileName(path); - var resource = ResourceManager.Parse(path, _currentFile, _currentNamespace); - using var stream = resource.OpenStream(); + var resource = PathExpressionEvaluator.Get(path, _currentFile, _currentNamespace); + using var stream = resource.Open(); try { diff --git a/LevelTemplateCreator/Assets/AssetInfo.cs b/LevelTemplateCreator/Assets/AssetSource.cs similarity index 69% rename from LevelTemplateCreator/Assets/AssetInfo.cs rename to LevelTemplateCreator/Assets/AssetSource.cs index e15e7ea..1d6ed54 100644 --- a/LevelTemplateCreator/Assets/AssetInfo.cs +++ b/LevelTemplateCreator/Assets/AssetSource.cs @@ -5,4 +5,4 @@ using System.Threading.Tasks; namespace LevelTemplateCreator.Assets; -record AssetInfo(string SourceFile, string Namespace); \ No newline at end of file +public record struct AssetSource(string SourceFile, string Namespace); \ No newline at end of file diff --git a/LevelTemplateCreator/Assets/GroundCoverAsset.cs b/LevelTemplateCreator/Assets/GroundCoverAsset.cs index 326be85..6b18968 100644 --- a/LevelTemplateCreator/Assets/GroundCoverAsset.cs +++ b/LevelTemplateCreator/Assets/GroundCoverAsset.cs @@ -1,13 +1,18 @@ -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Main; +using Grille.BeamNgLib.SceneTree.Main; namespace LevelTemplateCreator.Assets; -internal class GroundCoverAsset : Asset +public class GroundCoverAsset : Asset { public const string ClassName = GroundCover.ClassName; public GroundCover GroundCover => Object; - public GroundCoverAsset(GroundCover item, AssetInfo info) : base(item, info) { } + public GroundCoverAsset(GroundCover item, AssetSource info) : base(item, info) { } + + public override GroundCover GetCopy() + { + var dict = Object.Dict; + return new GroundCover(dict); + } } diff --git a/LevelTemplateCreator/Assets/GroundCoverBuilder.cs b/LevelTemplateCreator/Assets/GroundCoverBuilder.cs index 0b7817f..baf43eb 100644 --- a/LevelTemplateCreator/Assets/GroundCoverBuilder.cs +++ b/LevelTemplateCreator/Assets/GroundCoverBuilder.cs @@ -1,5 +1,5 @@ -using LevelTemplateCreator.Collections; -using LevelTemplateCreator.SceneTree.Main; +using Grille.BeamNgLib.Collections; +using Grille.BeamNgLib.SceneTree.Main; using System; using System.Collections.Generic; using System.Linq; @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace LevelTemplateCreator.Assets; -internal class GroundCoverBuilder : IKeyed +public class GroundCoverBuilder : IKeyed { GroundCoverAsset _groundCover; @@ -23,7 +23,8 @@ public GroundCoverBuilder(GroundCoverAsset groundCover) public void AddInstance(GroundCoverInstance instance) { - var copy = instance.Copy(); + var dict = new JsonDict(instance.Dict); + var copy = new GroundCoverInstance(dict); copy.Parent.Remove(); _instances.Add(copy); } diff --git a/LevelTemplateCreator/Assets/LevelObjectsAsset.cs b/LevelTemplateCreator/Assets/LevelObjectsAsset.cs index 670d564..779e3d9 100644 --- a/LevelTemplateCreator/Assets/LevelObjectsAsset.cs +++ b/LevelTemplateCreator/Assets/LevelObjectsAsset.cs @@ -1,5 +1,5 @@ -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Main; +using Grille.BeamNgLib.SceneTree; +using Grille.BeamNgLib.SceneTree.Main; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -9,14 +9,14 @@ namespace LevelTemplateCreator.Assets; -internal class LevelObjectsAsset : Asset +public class LevelObjectsAsset : Asset { public const string ClassName = "LevelObjects"; Collection Items; - public LevelObjectsAsset(JsonDictWrapper data, AssetInfo info) : base(data, info) + public LevelObjectsAsset(JsonDictWrapper data, AssetSource info) : base(data, info) { Items = new Collection(); @@ -62,6 +62,11 @@ public void Apply(SimGroupLevelObjects group) } } + public override JsonDictWrapper GetCopy() + { + throw new NotImplementedException(); + } + public override string ToString() { return DisplayName; diff --git a/LevelTemplateCreator/Assets/MaterialAsset.cs b/LevelTemplateCreator/Assets/MaterialAsset.cs index 29f7c3c..8669aef 100644 --- a/LevelTemplateCreator/Assets/MaterialAsset.cs +++ b/LevelTemplateCreator/Assets/MaterialAsset.cs @@ -1,17 +1,12 @@ -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Art; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Grille.BeamNgLib.SceneTree.Art; + namespace LevelTemplateCreator.Assets; -abstract class MaterialAsset : Asset where T : Material +public abstract class MaterialAsset : Asset where T : Material { public T Material => Object; - protected MaterialAsset(T obj, AssetInfo info) : base(obj, info) + protected MaterialAsset(T obj, AssetSource info) : base(obj, info) { } } diff --git a/LevelTemplateCreator/Assets/ObjectMaterialAsset.cs b/LevelTemplateCreator/Assets/ObjectMaterialAsset.cs index 035ea54..4423ba5 100644 --- a/LevelTemplateCreator/Assets/ObjectMaterialAsset.cs +++ b/LevelTemplateCreator/Assets/ObjectMaterialAsset.cs @@ -1,19 +1,24 @@ -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Art; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Grille.BeamNgLib.SceneTree.Art; +using static System.Windows.Forms.AxHost; + namespace LevelTemplateCreator.Assets; -internal class ObjectMaterialAsset : MaterialAsset +public class ObjectMaterialAsset : MaterialAsset { public const string ClassName = ObjectMaterial.ClassName; - public ObjectMaterialAsset(ObjectMaterial item, AssetInfo info) : base(item, info) + public ObjectMaterialAsset(ObjectMaterial item, AssetSource info) : base(item, info) { //Material = new ObjectMaterial(item.Dict); } + + public override ObjectMaterial GetCopy() + { + var clone = new JsonDict(Object.Dict); + var stages = new JsonDict[4] { new(Object.Stage0.Dict), new(Object.Stage1.Dict), new(Object.Stage2.Dict), new(Object.Stage3.Dict) }; + clone["Stages"] = stages; + + return new ObjectMaterial(clone); + } } diff --git a/LevelTemplateCreator/Assets/TerrainMaterialAsset.cs b/LevelTemplateCreator/Assets/TerrainMaterialAsset.cs index 5c624ee..fa5ed73 100644 --- a/LevelTemplateCreator/Assets/TerrainMaterialAsset.cs +++ b/LevelTemplateCreator/Assets/TerrainMaterialAsset.cs @@ -1,21 +1,15 @@ -using LevelTemplateCreator.IO.Resources; -using LevelTemplateCreator.SceneTree; -using LevelTemplateCreator.SceneTree.Art; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Grille.BeamNgLib.SceneTree.Art; +using LevelTemplateCreator.IO.Resources; namespace LevelTemplateCreator.Assets; -internal class TerrainMaterialAsset : MaterialAsset +public class TerrainMaterialAsset : MaterialAsset { public const string ClassName = TerrainMaterial.ClassName; public float SquareSize { get; } - public TerrainMaterialAsset(TerrainMaterial item, AssetInfo info) : base(item, info) + public TerrainMaterialAsset(TerrainMaterial item, AssetSource info) : base(item, info) { Material.TryPopValue("squareSize", out float squareSize, 1); SquareSize = squareSize; @@ -39,4 +33,10 @@ void SetLayerIfEmpty(TerrainMaterialTextureLayer layer, string value) layer.Texture.Value = value; } } + + public override TerrainMaterial GetCopy() + { + var dict = new JsonDict(Object.Dict); + return new TerrainMaterial(dict); + } } diff --git a/LevelTemplateCreator/Collections/IKeyed.cs b/LevelTemplateCreator/Collections/IKeyed.cs deleted file mode 100644 index 666368f..0000000 --- a/LevelTemplateCreator/Collections/IKeyed.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.Collections; - -internal interface IKeyed -{ - public string? Key { get; } -} diff --git a/LevelTemplateCreator/EnvironmentInfo.cs b/LevelTemplateCreator/EnvironmentInfo.cs index 9c7feba..71b0514 100644 --- a/LevelTemplateCreator/EnvironmentInfo.cs +++ b/LevelTemplateCreator/EnvironmentInfo.cs @@ -1,11 +1,12 @@ -using LevelTemplateCreator.IO; +using Grille.BeamNgLib.IO; +using Grille.BeamNgLib.IO.Resources; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace LevelTemplateCreator; +namespace Grille.BeamNgLib; public static class EnvironmentInfo { @@ -127,7 +128,7 @@ static public void TryFindUserDir() { UserData.TryFindValidPath( [ - $"C:\\Users\\{System.Environment.UserName}\\AppData\\Local\\BeamNG.drive", + $"C:\\Users\\{Environment.UserName}\\AppData\\Local\\BeamNG.drive", ]); } @@ -155,7 +156,7 @@ static public void Load() static public void Save() { - var dict = new Dictionary(){ + var dict = new JsonDict(){ { "gamepath", GameData.Path }, { "userpath", UserData.Path }, { "packages", Packages.Path }, diff --git a/LevelTemplateCreator/GUI/AssetViewBox.cs b/LevelTemplateCreator/GUI/AssetViewBox.cs index ab5c4db..d5d83d2 100644 --- a/LevelTemplateCreator/GUI/AssetViewBox.cs +++ b/LevelTemplateCreator/GUI/AssetViewBox.cs @@ -218,7 +218,7 @@ void DrawItem(Graphics g, Asset item, int index, int position) { sb.AppendLine(item.Description); } - sb.AppendLine(item.Object.Class.Value); + sb.AppendLine(item.Class); sb.AppendLine(item.SourceFile); g.DrawString(sb.ToString(), Font, brush, boundsText); diff --git a/LevelTemplateCreator/GUI/LevelSettings.cs b/LevelTemplateCreator/GUI/LevelSettings.cs index 6917fb5..3f18706 100644 --- a/LevelTemplateCreator/GUI/LevelSettings.cs +++ b/LevelTemplateCreator/GUI/LevelSettings.cs @@ -14,9 +14,9 @@ namespace LevelTemplateCreator.GUI; internal partial class LevelSettings : UserControl { - Level? _level; + LevelExporter? _level; - public void SetLevel(Level level) + public void SetLevel(LevelExporter level) { _level = level; diff --git a/LevelTemplateCreator/GUI/MainForm.cs b/LevelTemplateCreator/GUI/MainForm.cs index 83429e6..8f9ada9 100644 --- a/LevelTemplateCreator/GUI/MainForm.cs +++ b/LevelTemplateCreator/GUI/MainForm.cs @@ -1,22 +1,24 @@ using System.Diagnostics; using System.Text; +using Grille.BeamNgLib; +using Grille.BeamNgLib.IO; +using Grille.BeamNgLib.Logging; using LevelTemplateCreator.Assets; using LevelTemplateCreator.GUI; -using LevelTemplateCreator.IO; namespace LevelTemplateCreator { public partial class MainForm : Form { AssetLibary AssetLibary { get; set; } - Level Level { get; set; } + LevelExporter Level { get; set; } public MainForm() { InitializeComponent(); AssetLibary = new AssetLibary(); - Level = new Level(AssetLibary); + Level = new LevelExporter(AssetLibary); LevelSettings.ButtonSave.Click += (object? sender, EventArgs e) => { @@ -110,7 +112,6 @@ void Export(string path) catch (Exception e) { ExceptionBox.Show(this, e); - if (Program.Debug) throw; } @@ -144,7 +145,7 @@ void LoadContent() AssetLibary.Clear(); - var loader = new AssetLibaryLoader(AssetLibary) { Debug = false }; + var loader = new AssetLibaryLoader(AssetLibary) { Debug = true }; loader.LoadDirectory(EnvironmentInfo.Packages.Path); if (ZipFileManager.Count > 0) diff --git a/LevelTemplateCreator/GUI/SettingsForm.cs b/LevelTemplateCreator/GUI/SettingsForm.cs index 539b870..bef9bd9 100644 --- a/LevelTemplateCreator/GUI/SettingsForm.cs +++ b/LevelTemplateCreator/GUI/SettingsForm.cs @@ -1,4 +1,5 @@ -using System; +using Grille.BeamNgLib; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; diff --git a/LevelTemplateCreator/GUI/TerrainSettings.Designer.cs b/LevelTemplateCreator/GUI/TerrainSettings.Designer.cs index 09a7a6d..1a7f932 100644 --- a/LevelTemplateCreator/GUI/TerrainSettings.Designer.cs +++ b/LevelTemplateCreator/GUI/TerrainSettings.Designer.cs @@ -50,10 +50,10 @@ private void InitializeComponent() // numericWorldSize.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; numericWorldSize.DecimalPlaces = 2; - numericWorldSize.Location = new Point(101, 32); + numericWorldSize.Location = new Point(103, 32); numericWorldSize.Maximum = new decimal(new int[] { 100000, 0, 0, 0 }); numericWorldSize.Name = "numericWorldSize"; - numericWorldSize.Size = new Size(477, 23); + numericWorldSize.Size = new Size(475, 23); numericWorldSize.TabIndex = 3; numericWorldSize.ValueChanged += numericUpDownWorldSize_ValueChanged; // @@ -62,9 +62,9 @@ private void InitializeComponent() comboBoxRes.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; comboBoxRes.FormattingEnabled = true; comboBoxRes.Items.AddRange(new object[] { "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768", "65536" }); - comboBoxRes.Location = new Point(101, 3); + comboBoxRes.Location = new Point(103, 3); comboBoxRes.Name = "comboBoxRes"; - comboBoxRes.Size = new Size(477, 23); + comboBoxRes.Size = new Size(475, 23); comboBoxRes.TabIndex = 4; comboBoxRes.SelectedIndexChanged += comboBoxRes_SelectedIndexChanged; // @@ -72,10 +72,10 @@ private void InitializeComponent() // numericSquareSize.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; numericSquareSize.DecimalPlaces = 2; - numericSquareSize.Location = new Point(101, 61); + numericSquareSize.Location = new Point(103, 61); numericSquareSize.Maximum = new decimal(new int[] { 100000, 0, 0, 0 }); numericSquareSize.Name = "numericSquareSize"; - numericSquareSize.Size = new Size(477, 23); + numericSquareSize.Size = new Size(475, 23); numericSquareSize.TabIndex = 5; numericSquareSize.ValueChanged += numericUpDownSquareSize_ValueChanged; // @@ -83,10 +83,10 @@ private void InitializeComponent() // numericMaxHeight.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; numericMaxHeight.DecimalPlaces = 2; - numericMaxHeight.Location = new Point(101, 90); + numericMaxHeight.Location = new Point(103, 90); numericMaxHeight.Maximum = new decimal(new int[] { 100000, 0, 0, 0 }); numericMaxHeight.Name = "numericMaxHeight"; - numericMaxHeight.Size = new Size(477, 23); + numericMaxHeight.Size = new Size(475, 23); numericMaxHeight.TabIndex = 6; numericMaxHeight.ValueChanged += numericUpDownMaxHeight_ValueChanged; // @@ -135,7 +135,7 @@ private void InitializeComponent() tableLayoutPanel1.AutoSize = true; tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink; tableLayoutPanel1.ColumnCount = 2; - tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100F)); tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); tableLayoutPanel1.Controls.Add(numericBaseHeight, 1, 4); tableLayoutPanel1.Controls.Add(numericMaxHeight, 1, 3); @@ -163,10 +163,10 @@ private void InitializeComponent() // numericBaseHeight.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; numericBaseHeight.DecimalPlaces = 2; - numericBaseHeight.Location = new Point(101, 119); + numericBaseHeight.Location = new Point(103, 119); numericBaseHeight.Maximum = new decimal(new int[] { 100000, 0, 0, 0 }); numericBaseHeight.Name = "numericBaseHeight"; - numericBaseHeight.Size = new Size(477, 23); + numericBaseHeight.Size = new Size(475, 23); numericBaseHeight.TabIndex = 12; numericBaseHeight.ValueChanged += numericBaseHeight_ValueChanged; // diff --git a/LevelTemplateCreator/GUI/TerrainSettings.cs b/LevelTemplateCreator/GUI/TerrainSettings.cs index c54fd7b..1852253 100644 --- a/LevelTemplateCreator/GUI/TerrainSettings.cs +++ b/LevelTemplateCreator/GUI/TerrainSettings.cs @@ -1,4 +1,5 @@ -using System; +using Grille.BeamNgLib; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; diff --git a/LevelTemplateCreator/IO/Resources/FileResource.cs b/LevelTemplateCreator/IO/Resources/FileResource.cs deleted file mode 100644 index cdad6a4..0000000 --- a/LevelTemplateCreator/IO/Resources/FileResource.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.IO.Resources; - -internal class FileResource : Resource -{ - public string Path { get; } - - public FileResource(string name, string path) : base(name) - { - Path = path; - } - - public override Stream OpenStream() - { - return new FileStream(Path, FileMode.Open); - } -} diff --git a/LevelTemplateCreator/IO/Resources/ResourceCollection.cs b/LevelTemplateCreator/IO/Resources/ResourceCollection.cs deleted file mode 100644 index 484fa7e..0000000 --- a/LevelTemplateCreator/IO/Resources/ResourceCollection.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections; -using System.Globalization; -using System.Collections.Generic; -using System.IO.Compression; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using LevelTemplateCreator.SceneTree.Art; -using LevelTemplateCreator.Collections; -using LevelTemplateCreator.Assets; - -namespace LevelTemplateCreator.IO.Resources; - -internal class ResourceCollection : KeyedCollection -{ - public string Register(string entry) - { - var resource = ResourceManager.Parse(entry); - return TryAdd(resource); - } - - public string RegisterRelative(string entry, AssetInfo info) - { - var resource = ResourceManager.Parse(entry, info.SourceFile, info.Namespace); - return TryAdd(resource); - } - - string TryAdd(Resource resource) - { - var key = resource.Name; - if (ContainsKey(key)) - return key; - Add(resource); - return key; - } - - public void Save(string path) - { - foreach (var resource in this) - { - resource.SaveToDirectory(path); - } - } -} diff --git a/LevelTemplateCreator/IO/Resources/ResourceManager.cs b/LevelTemplateCreator/IO/Resources/ResourceManager.cs deleted file mode 100644 index f12c537..0000000 --- a/LevelTemplateCreator/IO/Resources/ResourceManager.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; - -namespace LevelTemplateCreator.IO.Resources; - -internal static class ResourceManager -{ - public static Resource Parse(string entry, string rootPath, string @namespace) - { - if (entry.StartsWith("$")) - { - var name = entry.Substring(1); - var key = '$' + @namespace + name; - return ParseVariable(key); - } - return Parse(entry, rootPath); - } - - public static Resource Parse(string entry, string rootPath) - { - if (entry.StartsWith('.')) - { - return ParseRelative(entry, rootPath); - } - return Parse(entry); - } - - public static Resource Parse(string entry) - { - if (entry.StartsWith("$")) - { - return ParseVariable(entry); - } - - entry = entry.Replace("\\", "/"); - - if (entry.StartsWith('#')) - { - return ParseColor(entry); - } - else if (entry.StartsWith('/')) - { - return ParseAbsolute(entry); - } - else - { - return ParseAbsolute('/' + entry); - } - } - - static Resource ParseVariable(string key) - { - if (Constants.TryGet(key, out var value)) - { - return Parse(value); - } - else - { - throw new Exception($"Constant '{key}' not defined."); - } - } - - static Resource ParseRelative(string rpath, string rootPath) - { - var abspackpath = Path.GetFullPath(EnvironmentInfo.Packages.Path); - var dirpath = Path.GetDirectoryName(rootPath); - if (dirpath == null) - throw new Exception(); - var path = Path.GetFullPath(Path.Combine(dirpath, rpath)); - var subpath = path.Substring(abspackpath.Length); - - return Parse(subpath); - } - - static Resource ParseColor(string hex) - { - var name = hex.Substring(1); - - var key = $"#{name}.png"; - - int color; - - if (!int.TryParse(name, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out color)) - { - SolidColorNames.TryGet(hex, out color); - } - - var resource = new SolidColorResource(key, color); - return resource; - } - - static Resource ParseAbsolute(string path) - { - var split = path.ToLower().Split([Path.PathSeparator, Path.AltDirectorySeparatorChar]); - - if (split[1] == "levels") - { - var level = split[2]; - var filename = split[split.Length - 1]; - var key = $"beamng.{level}.{filename}"; - var zippath = $"{EnvironmentInfo.GameData.Path}/content/levels/{level}.zip"; - if (File.Exists(zippath)) - { - var subpath = path.Substring(1); - var resource = new ZipFileResource(key, zippath, subpath); - return resource; - } - } - - { - var filename = path.Substring(1).Replace("/", "."); - var key = $"local.{filename}"; - var fpath = Path.Join(EnvironmentInfo.Packages.Path, path); - var resource = new FileResource(key, fpath); - return resource; - } - } -} diff --git a/LevelTemplateCreator/IO/TerrainV9Serializer.cs b/LevelTemplateCreator/IO/TerrainV9Serializer.cs deleted file mode 100644 index 18c7efb..0000000 --- a/LevelTemplateCreator/IO/TerrainV9Serializer.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using GGL.IO; -using LevelTemplateCreator.SceneTree.Art; - -namespace LevelTemplateCreator.IO; - -static class TerrainV9Serializer -{ - public static void Serialize(TerrainInfo info, ICollection materials, string path) - { - using var stream = new FileStream(path, FileMode.Create); - Serialize(info, materials, stream); - } - - public static void Serialize(TerrainInfo info, ICollection materials, Stream stream) - { - using var bw = new BinaryViewWriter(stream); - - bw.WriteByte(9); - bw.WriteUInt32((uint)info.Resolution); - - long size = info.Resolution * (long)info.Resolution; - - float u16max = ushort.MaxValue; - - float height = info.Height / info.MaxHeight * u16max; - if (height > u16max) - height = u16max; - - ushort u16height = (ushort)height; - - for (int i = 0; i < size; i++) - { - bw.WriteUInt16(u16height); - } - - bw.Seek(size, SeekOrigin.Current); - - bw.WriteUInt32((uint)materials.Count); - - foreach (var material in materials) - { - bw.WriteString(material, LengthPrefix.Byte, Encoding.UTF8); - } - } -} diff --git a/LevelTemplateCreator/Level.cs b/LevelTemplateCreator/LevelExporter.cs similarity index 50% rename from LevelTemplateCreator/Level.cs rename to LevelTemplateCreator/LevelExporter.cs index 760fec6..92e7ab7 100644 --- a/LevelTemplateCreator/Level.cs +++ b/LevelTemplateCreator/LevelExporter.cs @@ -1,5 +1,4 @@ -using LevelTemplateCreator.IO; -using LevelTemplateCreator.Assets; +using LevelTemplateCreator.Assets; using System; using System.Collections.Generic; using System.IO; @@ -7,15 +6,18 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; -using LevelTemplateCreator.SceneTree.Art; -using LevelTemplateCreator.SceneTree.Main; using LevelTemplateCreator.IO.Resources; -using LevelTemplateCreator.Properties; -using LevelTemplateCreator.GUI; +using Grille.BeamNgLib; +using Grille.BeamNgLib.SceneTree.Main; +using Grille.BeamNgLib.SceneTree.Art; +using Grille.BeamNgLib.IO; +using Grille.BeamNgLib.Logging; +using System.Numerics; +using Grille.BeamNgLib.IO.Resources; namespace LevelTemplateCreator; -internal class Level +public class LevelExporter { public AssetLibary Libary { get; } @@ -23,20 +25,19 @@ internal class Level public string Namespace { get; set; } - public LevelInfo Info { get; set; } + public Level Level { get; set; } - public TerrainInfo Terrain { get; set; } + public LevelInfo Info => Level.Info; + + public TerrainInfo Terrain => Level.Terrain; public ErrorLogger Errors { get; } - public Level(AssetLibary libary) + public LevelExporter(AssetLibary libary) { Namespace = "new_pbr_template"; - Info = new LevelInfo(); - Terrain = new TerrainInfo() - { - Resolution = 1024, - }; + Level = new(); + Level.Terrain.Resolution = 1024; Content = new AssetLibaryContent(); Libary = libary; Errors = new ErrorLogger(); @@ -50,18 +51,59 @@ public TerrainBlock BuildTerrainBlock() return terrain; } - public TerrainMaterialLibary BuildTerrainMaterialLibary() + public ArtGroupRoot BuildArtGroup() + { + var root = new ArtGroupRoot(); + + BuildArtGroupTerrain(root); + BuildArtGroupGroundcover(root); + + return root; + } + + void BuildArtGroupTerrain(ArtGroupRoot root) { var path = $"/levels/{Namespace}/art/terrains"; - var lib = new TerrainMaterialLibary(path, Terrain.SquareSize); - lib.AddAssets(Content.TerrainMaterials, Errors); - lib.CreateTerrainMaterialTextureSet($"{Namespace}_TerrainMaterialTextureSet"); + var group = root.Terrains; + var materials = group.MaterialItems; - return lib; + foreach (var asset in Content.TerrainMaterials) + { + float squareSize = asset switch + { + TerrainMaterialAsset tma => tma.SquareSize, + _ => 1 + }; + + var copy = asset.GetCopy(); + copy.CreatePersistentId(); + copy.MultiplyMappingScale(squareSize / Terrain.SquareSize); + copy.EvalPathExpressions(asset, path, group.Resources); + materials.Add(copy); + } + + var textureSetName = $"{Namespace}_TerrainMaterialTextureSet"; + materials.Add(new TerrainMaterialTextureSet(textureSetName)); } - public SimGroup BuildMissionGroup() + void BuildArtGroupGroundcover(ArtGroupRoot root) + { + var path = $"/levels/{Namespace}/art/groundcover"; + + var group = root.Groundcover; + var materials = group.MaterialItems; + + foreach (var asset in Content.ObjectMaterials) + { + var copy = asset.GetCopy(); + copy.EvalPathExpressions(asset, path, group.Resources); + materials.Add(copy); + } + + } + + public SimGroupRoot BuildSimGroup() { var root = new SimGroupRoot(); var group = root.MissionGroup; @@ -99,34 +141,16 @@ public void SetContent(Asset[] assets) public void Export(string path) { - Directory.CreateDirectory(Path.Combine(path, "art/terrains")); - - Directory.CreateDirectory(Path.Combine(path, "art/objects")); - - var objpath = $"/levels/{Namespace}/art/objects"; - var lib = new ObjectMaterialLibary(objpath); - lib.AddAssets(Content.ObjectMaterials, Errors); - - lib.SerializeItems(Path.Combine(path, "art/objects/" + MaterialLibary.FileName)); - lib.Textures.Save(Path.Combine(path, "art/objects")); - - var terrainMaterials = BuildTerrainMaterialLibary(); - - terrainMaterials.SerializeItems(Path.Combine(path, "art/terrains/" + MaterialLibary.FileName)); - - var texturespath = Path.Combine(path, "art/terrains"); - - terrainMaterials.Textures.Save(texturespath); - + LevelInfoSerializer.Serialize(Level, Path.Combine(path, "info.json")); + TerrainV9Serializer.Serialize(Terrain, Content.TerrainMaterials.Keys, Path.Combine(path, "terrain.ter")); Content.Preview?.Save(Path.Combine(path, "preview.png")); + var simPath = Path.Combine(path, "main"); + var artPath = Path.Combine(path, "art"); - BuildMissionGroup().SaveTree(Path.Combine(path, "main")); - - TerrainV9Serializer.Serialize(Terrain, Content.TerrainMaterials.Keys, Path.Combine(path, "terrain.ter")); - - LevelInfoSerializer.Serialize(this, Path.Combine(path, "info.json")); + BuildSimGroup().SaveTree(simPath); + BuildArtGroup().SaveTree(artPath); if (ZipFileManager.Count > 0) { diff --git a/LevelTemplateCreator/LevelTemplateCreator.csproj b/LevelTemplateCreator/LevelTemplateCreator.csproj index f016061..0ea22b1 100644 --- a/LevelTemplateCreator/LevelTemplateCreator.csproj +++ b/LevelTemplateCreator/LevelTemplateCreator.csproj @@ -6,7 +6,7 @@ 12 enable true - enable + ../Assets/Grille.BeamNG.ico @@ -17,6 +17,10 @@ + + + + True diff --git a/LevelTemplateCreator/Logger.cs b/LevelTemplateCreator/Logger.cs deleted file mode 100644 index 9c644df..0000000 --- a/LevelTemplateCreator/Logger.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator; - -enum LoggerColor -{ - Default = ConsoleColor.Gray, - Red = ConsoleColor.Red, -} - -internal static class Logger -{ - public static void WriteLine() { - Console.WriteLine(); - } - - public static void WriteLine(string text) - { - Console.WriteLine(text); - } - - public static void WriteLine(string text, LoggerColor color) - { - Console.ForegroundColor = (ConsoleColor)color; - Console.WriteLine(text); - Console.ForegroundColor = (ConsoleColor)LoggerColor.Default; - } - - public static void Error() - { - - } -} diff --git a/LevelTemplateCreator/MaterialExtension.cs b/LevelTemplateCreator/MaterialExtension.cs new file mode 100644 index 0000000..1f23673 --- /dev/null +++ b/LevelTemplateCreator/MaterialExtension.cs @@ -0,0 +1,23 @@ +using Grille.BeamNgLib.IO.Resources; +using Grille.BeamNgLib.SceneTree.Art; +using LevelTemplateCreator.Assets; +using LevelTemplateCreator.IO.Resources; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LevelTemplateCreator; +internal static class MaterialExtension +{ + public static void EvalPathExpressions(this Material material, Asset asset, string path, ResourceCollection textures) + { + foreach (var texture in material.EnumerateTexturePaths()) + { + var resource = PathExpressionEvaluator.Get(texture.Value, asset.Info); + textures.Add(resource); + texture.Value = Path.Combine(path, resource.DynamicName); + } + } +} diff --git a/LevelTemplateCreator/Program.cs b/LevelTemplateCreator/Program.cs index 8ce91c2..54623af 100644 --- a/LevelTemplateCreator/Program.cs +++ b/LevelTemplateCreator/Program.cs @@ -1,4 +1,6 @@ +using Grille.BeamNgLib.Logging; using System.Globalization; +using System.Threading; namespace LevelTemplateCreator; @@ -17,6 +19,9 @@ internal static class Program [STAThread] static void Main() { + using var stream = new FileStream("console.log", FileMode.Create); + Logger.OutputStream = stream; + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; ApplicationConfiguration.Initialize(); Application.Run(new MainForm()); diff --git a/LevelTemplateCreator/IO/Resources/Constants.cs b/LevelTemplateCreator/Resouces/Constants.cs similarity index 94% rename from LevelTemplateCreator/IO/Resources/Constants.cs rename to LevelTemplateCreator/Resouces/Constants.cs index d353881..777c9fc 100644 --- a/LevelTemplateCreator/IO/Resources/Constants.cs +++ b/LevelTemplateCreator/Resouces/Constants.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; namespace LevelTemplateCreator.IO.Resources; -internal static class Constants +public static class Constants { readonly static Dictionary _dict; diff --git a/LevelTemplateCreator/Resouces/PathExpressionEvaluator.cs b/LevelTemplateCreator/Resouces/PathExpressionEvaluator.cs new file mode 100644 index 0000000..de587ed --- /dev/null +++ b/LevelTemplateCreator/Resouces/PathExpressionEvaluator.cs @@ -0,0 +1,108 @@ +using Grille.BeamNgLib; +using Grille.BeamNgLib.IO.Resources; +using LevelTemplateCreator.Assets; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LevelTemplateCreator.IO.Resources; + +public static class PathExpressionEvaluator +{ + public static Resource Get(string entry, AssetSource source) + { + return Get(entry, source.SourceFile, source.Namespace); + } + + public static Resource Get(string entry) + { + return Get(entry, string.Empty, string.Empty); + } + + public static Resource Get(string entry, string filePath) + { + return Get(entry, filePath, string.Empty); + } + + public static Resource Get(string entry, string filePath, string @namespace) + { + if (entry.StartsWith("$")) + { + return ParseVariable(entry, @namespace); + } + else if (entry.StartsWith('#')) + { + return ParseColor(entry); + } + else if (entry.StartsWith('.')) + { + return ParseRelative(entry, EnvironmentInfo.Packages.Path, filePath); + } + return PathEvaluator.Get(entry, EnvironmentInfo.GameData.Path, EnvironmentInfo.UserData.Path); + } + + static Resource ParseRelative(string entry, string rootPath, string filePath) + { + entry = entry.Replace("\\", "/"); + + if (string.IsNullOrEmpty(rootPath)) + { + throw new ArgumentException("Relative path not supported, RootPath is empty."); + } + if (string.IsNullOrEmpty(filePath)) + { + throw new ArgumentException("Relative path not supported, FilePath is empty."); + } + + var abspackpath = Path.GetFullPath(rootPath); + var dirpath = Path.GetDirectoryName(filePath); + if (dirpath == null) + { + throw new InvalidOperationException($"Relative path directory was null '{entry}'"); + } + + var path = Path.GetFullPath(Path.Combine(dirpath, entry)); + var subpath = path.Substring(abspackpath.Length); + + var filename = subpath.Substring(1).Replace("/", "_").Replace("\\", "_"); + var key = $"local.{filename}"; + var fpath = Path.Join(rootPath, subpath); + var resource = new FileResource(key, fpath, false); + return resource; + } + + static Resource ParseVariable(string entry, string @namespace) + { + var name = entry.Substring(1); + var key = '$' + @namespace + name; + + if (Constants.TryGet(key, out var value)) + { + return Get(value); + } + else + { + throw new Exception($"Constant '{key}' not defined."); + } + } + + static Resource ParseColor(string hex) + { + var name = hex.Substring(1); + + var key = $"#{name}.png"; + + int color; + + if (!int.TryParse(name, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out color)) + { + SolidColorNames.TryGet(hex, out color); + } + + var resource = new SolidColorResource(key, color); + return resource; + } +} diff --git a/LevelTemplateCreator/IO/Resources/SolidColorNames.cs b/LevelTemplateCreator/Resouces/SolidColorNames.cs similarity index 98% rename from LevelTemplateCreator/IO/Resources/SolidColorNames.cs rename to LevelTemplateCreator/Resouces/SolidColorNames.cs index 2074328..fe5f26b 100644 --- a/LevelTemplateCreator/IO/Resources/SolidColorNames.cs +++ b/LevelTemplateCreator/Resouces/SolidColorNames.cs @@ -7,7 +7,7 @@ namespace LevelTemplateCreator.IO.Resources; -internal static class SolidColorNames +public static class SolidColorNames { static readonly Dictionary _colors; diff --git a/LevelTemplateCreator/IO/Resources/SolidColorResource.cs b/LevelTemplateCreator/Resouces/SolidColorResource.cs similarity index 85% rename from LevelTemplateCreator/IO/Resources/SolidColorResource.cs rename to LevelTemplateCreator/Resouces/SolidColorResource.cs index 35fc737..e372ca0 100644 --- a/LevelTemplateCreator/IO/Resources/SolidColorResource.cs +++ b/LevelTemplateCreator/Resouces/SolidColorResource.cs @@ -5,14 +5,15 @@ using System.Threading.Tasks; using System.Drawing.Imaging; using System.Runtime.CompilerServices; +using Grille.BeamNgLib.IO.Resources; namespace LevelTemplateCreator.IO.Resources; -internal class SolidColorResource : Resource +public class SolidColorResource : Resource { public byte[] Bytes { get; } - public SolidColorResource(string name, int color, int size = 1024) : base(name) + public SolidColorResource(string name, int color, int size = 1024) : base(name, false) { const int mask = -16777216; @@ -27,7 +28,7 @@ public SolidColorResource(string name, int color, int size = 1024) : base(name) Bytes = stream.ToArray(); } - public override Stream OpenStream() + public override Stream Open() { return new MemoryStream(Bytes); } diff --git a/LevelTemplateCreator/SceneTree/Art/Material.cs b/LevelTemplateCreator/SceneTree/Art/Material.cs deleted file mode 100644 index ac42321..0000000 --- a/LevelTemplateCreator/SceneTree/Art/Material.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LevelTemplateCreator.Assets; -using LevelTemplateCreator.IO.Resources; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.SceneTree.Art; - -internal abstract class Material : JsonDictWrapper -{ - protected Material(JsonDict dict) : base(dict) - { - - } - - public abstract void ResolveTexturePaths(MaterialLibary libary, AssetInfo info); - - public override abstract Material Copy(); -} diff --git a/LevelTemplateCreator/SceneTree/Art/MaterialLibary.cs b/LevelTemplateCreator/SceneTree/Art/MaterialLibary.cs deleted file mode 100644 index dc0892c..0000000 --- a/LevelTemplateCreator/SceneTree/Art/MaterialLibary.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.DirectoryServices.ActiveDirectory; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; -using LevelTemplateCreator.IO; -using LevelTemplateCreator.IO.Resources; -using LevelTemplateCreator.Properties; -using LevelTemplateCreator.Assets; - -namespace LevelTemplateCreator.SceneTree.Art; - -internal abstract class MaterialLibary -{ - public const string FileName = "main.materials.json"; - - public string TexturesPath { get; } - - public ResourceCollection Textures { get; } - - public List Misc { get; } - - public abstract IEnumerable Materials { get; } - - public MaterialLibary(string path) - { - TexturesPath = path; - Misc = new(); - Textures = new(); - } -} - -internal abstract class MaterialLibary : MaterialLibary where T : Material -{ - public override List Materials { get; } - - public MaterialLibary(string path) : base(path) - { - Materials = new(); - } - - public abstract void AddAsset(TAsset asset) where TAsset : MaterialAsset; - - public void AddAssets(IEnumerable assets, ErrorLogger logger) where TAsset : MaterialAsset - { - foreach (var asset in assets) - { - try - { - AddAsset(asset); - } - catch (Exception e) { - logger.Add($"At {asset.DisplayName} From {asset.SourceFile}\n{e.Message}"); - } - } - } - - - public string[] GetMaterialNames() - { - var result = new string[Materials.Count]; - for (int i = 0; i < result.Length; i++) - { - result[i] = Materials[i].Name.Value; - } - return result; - } - - public void SerializeItems(string path) - { - using var stream = new FileStream(path, FileMode.Create); - SerializeItems(stream); - } - - public void SerializeItems(Stream stream) - { - var dict = new JsonDict(); - - foreach (var item in Materials) - { - dict[item.Name.Value] = item.Dict; - } - - foreach (var item in Misc) - { - dict[item.Name.Value] = item.Dict; - } - - JsonDictSerializer.Serialize(stream, dict, true); - } -} diff --git a/LevelTemplateCreator/SceneTree/Art/ObjectMaterialLibary.cs b/LevelTemplateCreator/SceneTree/Art/ObjectMaterialLibary.cs deleted file mode 100644 index 4910819..0000000 --- a/LevelTemplateCreator/SceneTree/Art/ObjectMaterialLibary.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.SceneTree.Art; - -internal class ObjectMaterialLibary : MaterialLibary -{ - public ObjectMaterialLibary(string path) : base(path) - { - } - - public override void AddAsset(TAsset asset) - { - var copy = asset.GetCopy(); - copy.ResolveTexturePaths(this, asset.Info); - Materials.Add(copy); - } -} diff --git a/LevelTemplateCreator/SceneTree/Art/TerrainMaterialLibary.cs b/LevelTemplateCreator/SceneTree/Art/TerrainMaterialLibary.cs deleted file mode 100644 index a5a95ab..0000000 --- a/LevelTemplateCreator/SceneTree/Art/TerrainMaterialLibary.cs +++ /dev/null @@ -1,39 +0,0 @@ -using LevelTemplateCreator.Assets; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LevelTemplateCreator.SceneTree.Art; - -internal class TerrainMaterialLibary : MaterialLibary -{ - readonly float _squareSize; - - public TerrainMaterialLibary(string path, float squareSize) : base(path) - { - _squareSize = squareSize; - } - - public override void AddAsset(TAsset asset) - { - float squareSize = asset switch - { - TerrainMaterialAsset tma => tma.SquareSize, - _ => 1 - }; - - var copy = asset.GetCopy(); - copy.CreatePersistentId(); - copy.MultiplyMappingScale(squareSize / _squareSize); - copy.ResolveTexturePaths(this, asset.Info); - Materials.Add(copy); - } - - public void CreateTerrainMaterialTextureSet(string name) - { - Misc.Add(new TerrainMaterialTextureSet(name)); - } -} diff --git a/LevelTemplateCreator/usings.cs b/LevelTemplateCreator/usings.cs index 62b04e0..2eea4e4 100644 --- a/LevelTemplateCreator/usings.cs +++ b/LevelTemplateCreator/usings.cs @@ -1 +1,7 @@ -global using JsonDict = System.Collections.Generic.Dictionary; \ No newline at end of file +global using System; +global using System.IO; +global using System.Collections.Generic; +global using System.Windows.Forms; +global using System.Drawing; + +global using JsonDict = System.Collections.Generic.Dictionary; \ No newline at end of file