diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 195779f..0298c8c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,8 +11,12 @@ jobs: runs-on: windows-latest steps: + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: '8.0.x' - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Extract version number id: extract_version shell: pwsh @@ -42,4 +46,4 @@ jobs: with: name: cmodconvert-${{ steps.extract_version.outputs.version }} path: Publish/ - + diff --git a/CmodConvert.Test/CmodConvert.Test.csproj b/CmodConvert.Test/CmodConvert.Test.csproj index 5804137..18bcc36 100644 --- a/CmodConvert.Test/CmodConvert.Test.csproj +++ b/CmodConvert.Test/CmodConvert.Test.csproj @@ -1,31 +1,20 @@  - - net6.0 - enable - enable + net8.0 true false - Andrew Tribick - ⓒ 2021–2023 Andrew Tribick - LICENSE - https://github.com/ajtribick/cmodconvert - git - true + false - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + \ No newline at end of file diff --git a/CmodConvert.sln b/CmodConvert.sln index 686391a..6bba464 100644 --- a/CmodConvert.sln +++ b/CmodConvert.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 @@ -9,6 +8,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .gitattributes = .gitattributes .gitignore = .gitignore + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props LICENSE = LICENSE README.md = README.md EndProjectSection @@ -18,7 +19,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "format", "format", "{0D856A format\cmod-binary.md = format\cmod-binary.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CmodConvert.Test", "CmodConvert.Test\CmodConvert.Test.csproj", "{FCBD5246-03B8-4744-918E-E4C021A08B67}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CmodConvert.Test", "CmodConvert.Test\CmodConvert.Test.csproj", "{FCBD5246-03B8-4744-918E-E4C021A08B67}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/CmodConvert/CmodConvert.csproj b/CmodConvert/CmodConvert.csproj index a9d3942..be46383 100644 --- a/CmodConvert/CmodConvert.csproj +++ b/CmodConvert/CmodConvert.csproj @@ -16,48 +16,31 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --> - - Exe - net6.0 - enable - enable - true - none - 0.1.1 - Andrew Tribick + net8.0 Convert Celestia CMOD format to Wavefront OBJ/MTL. - ⓒ 2021–2023 Andrew Tribick LICENSE - https://github.com/ajtribick/cmodconvert - git - 0.1.1.0 - 0.1.1.0 - true - none false - PreserveNewest True - + + PreserveNewest - - + - - + \ No newline at end of file diff --git a/CmodConvert/CmodData.cs b/CmodConvert/CmodData.cs index 308d23c..a89118c 100644 --- a/CmodConvert/CmodData.cs +++ b/CmodConvert/CmodData.cs @@ -18,14 +18,8 @@ namespace CmodConvert; -public class CmodData +public class CmodData(IReadOnlyCollection materials, IReadOnlyCollection meshes) { - public CmodData(IReadOnlyCollection materials, IReadOnlyCollection meshes) - { - Materials = materials; - Meshes = meshes; - } - - public IReadOnlyCollection Materials { get; } - public IReadOnlyCollection Meshes { get; } + public IReadOnlyCollection Materials { get; } = materials; + public IReadOnlyCollection Meshes { get; } = meshes; } diff --git a/CmodConvert/IO/CmodReader.Ascii.cs b/CmodConvert/IO/CmodReader.Ascii.cs index 9feee5d..78434a0 100644 --- a/CmodConvert/IO/CmodReader.Ascii.cs +++ b/CmodConvert/IO/CmodReader.Ascii.cs @@ -20,18 +20,11 @@ namespace CmodConvert.IO; public abstract partial class CmodReader { - private class Ascii : CmodReader + private class Ascii(Stream stream) : CmodReader { - private readonly Stream _stream; - - public Ascii(Stream stream) - { - _stream = stream; - } - public override async Task Read() { - using var reader = new TokenReader(_stream); + using var reader = new TokenReader(stream); var materials = new List(); var meshes = new List(); @@ -87,23 +80,13 @@ private static async Task ReadMaterial(TokenReader reader) break; case "blend": - switch (await reader.NextToken().ConfigureAwait(false)) + material.BlendMode = await reader.NextToken().ConfigureAwait(false) switch { - case "normal": - material.BlendMode = BlendMode.Normal; - break; - - case "add": - material.BlendMode = BlendMode.Additive; - break; - - case "premultiplied": - material.BlendMode = BlendMode.PremultipliedAlpha; - break; - - default: - throw new CmodException("Unknown blend mode"); - } + "normal" => (BlendMode?)BlendMode.Normal, + "add" => (BlendMode?)BlendMode.Additive, + "premultiplied" => (BlendMode?)BlendMode.PremultipliedAlpha, + _ => throw new CmodException("Unknown blend mode"), + }; break; case "texture0": diff --git a/CmodConvert/IO/CmodReader.Binary.cs b/CmodConvert/IO/CmodReader.Binary.cs index d135f16..3768514 100644 --- a/CmodConvert/IO/CmodReader.Binary.cs +++ b/CmodConvert/IO/CmodReader.Binary.cs @@ -20,18 +20,11 @@ namespace CmodConvert.IO; public abstract partial class CmodReader { - private class Binary : CmodReader + private class Binary(Stream stream) : CmodReader { - private readonly Stream _stream; - - public Binary(Stream stream) - { - _stream = stream; - } - public override async Task Read() { - using var reader = new BufferedReader(_stream); + using var reader = new BufferedReader(stream); var materials = new List(); var meshes = new List(); diff --git a/CmodConvert/IO/TokenReader.cs b/CmodConvert/IO/TokenReader.cs index 1b3fb5c..b4f0785 100644 --- a/CmodConvert/IO/TokenReader.cs +++ b/CmodConvert/IO/TokenReader.cs @@ -23,12 +23,14 @@ namespace CmodConvert.IO; internal sealed class TokenReader : IDataReader { + private static readonly char[] s_endTokenChars = [' ', '\t']; + private readonly TextReader _reader; private string? _line; private int _position; private bool _disposed; - public TokenReader(Stream stream, int capacity = 4096) + public TokenReader(Stream stream) { try { @@ -81,15 +83,15 @@ public TokenReader(Stream stream, int capacity = 4096) break; default: - var endToken = _line.IndexOfAny(new[] { ' ', '\t' }, _position + 1); + var endToken = _line.IndexOfAny(s_endTokenChars, _position + 1); if (endToken > 0) { _position = endToken + 1; - return _line.Substring(current, endToken - current); + return _line[current..endToken]; } _position = _line.Length; - return _line.Substring(current); + return _line[current..]; } } } diff --git a/CmodConvert/IO/WavefrontWriter.cs b/CmodConvert/IO/WavefrontWriter.cs index 6fdd602..c5a4c15 100644 --- a/CmodConvert/IO/WavefrontWriter.cs +++ b/CmodConvert/IO/WavefrontWriter.cs @@ -21,22 +21,13 @@ namespace CmodConvert.IO; -internal class WavefrontWriter +internal class WavefrontWriter(string objFile, string mtlFile) { - private readonly string _objFile; - private readonly string _mtlFile; - - public WavefrontWriter(string objFile, string mtlFile) - { - _objFile = objFile; - _mtlFile = mtlFile; - } - public Task Write(WavefrontMesh mesh) => Task.WhenAll(WriteMtl(mesh.Materials), WriteObj(mesh)); private async Task WriteMtl(IEnumerable materials) { - using var stream = new FileStream(_mtlFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true); + using var stream = new FileStream(mtlFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true); using var writer = new StreamWriter(stream, Encoding.ASCII); var i = 0; @@ -99,11 +90,11 @@ private async Task WriteMtl(IEnumerable materials) private async Task WriteObj(WavefrontMesh mesh) { - using var stream = new FileStream(_objFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true); + using var stream = new FileStream(objFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true); using var writer = new StreamWriter(stream, Encoding.ASCII); - var objDirectory = Path.GetDirectoryName(_objFile); - var mtlRelative = objDirectory != null ? Path.GetRelativePath(objDirectory, _mtlFile) : _mtlFile; + var objDirectory = Path.GetDirectoryName(objFile); + var mtlRelative = objDirectory != null ? Path.GetRelativePath(objDirectory, mtlFile) : mtlFile; await writer.WriteLineAsync($"mtllib {mtlRelative}").ConfigureAwait(false); diff --git a/CmodConvert/Material.cs b/CmodConvert/Material.cs index 7436127..aea778c 100644 --- a/CmodConvert/Material.cs +++ b/CmodConvert/Material.cs @@ -26,7 +26,7 @@ public class Material public float? SpecularPower { get; set; } public float? Opacity { get; set; } public BlendMode? BlendMode { get; set; } - public Dictionary Textures { get; } = new(); + public Dictionary Textures { get; } = []; public Material Clone() { diff --git a/CmodConvert/Mesh.cs b/CmodConvert/Mesh.cs index 45f7661..fb748c6 100644 --- a/CmodConvert/Mesh.cs +++ b/CmodConvert/Mesh.cs @@ -18,17 +18,11 @@ namespace CmodConvert; -public class Mesh +public class Mesh( + IReadOnlyList vertexAttributes, + IReadOnlyList primitives) { - public Mesh( - IReadOnlyList vertexAttributes, - IReadOnlyList primitives) - { - VertexAttributes = vertexAttributes; - Primitives = primitives; - } - - public int VertexCount => VertexAttributes.First().Count; - public IReadOnlyList VertexAttributes { get; } - public IReadOnlyList Primitives { get; } + public int VertexCount => VertexAttributes[0].Count; + public IReadOnlyList VertexAttributes { get; } = vertexAttributes; + public IReadOnlyList Primitives { get; } = primitives; } diff --git a/CmodConvert/Primitive.cs b/CmodConvert/Primitive.cs index 98af652..3c9e44e 100644 --- a/CmodConvert/Primitive.cs +++ b/CmodConvert/Primitive.cs @@ -18,16 +18,9 @@ namespace CmodConvert; -public class Primitive +public class Primitive(PrimitiveType primitiveType, int materialIndex, int count) { - public Primitive(PrimitiveType primitiveType, int materialIndex, int count) - { - PrimitiveType = primitiveType; - MaterialIndex = materialIndex; - Indices = new(count); - } - - public PrimitiveType PrimitiveType { get; } - public int MaterialIndex { get; } - public List Indices { get; } + public PrimitiveType PrimitiveType { get; } = primitiveType; + public int MaterialIndex { get; } = materialIndex; + public List Indices { get; } = new(count); } diff --git a/CmodConvert/VertexAttribute.Float1.cs b/CmodConvert/VertexAttribute.Float1.cs index d88b940..b25d6b1 100644 --- a/CmodConvert/VertexAttribute.Float1.cs +++ b/CmodConvert/VertexAttribute.Float1.cs @@ -22,11 +22,9 @@ namespace CmodConvert; public abstract partial class VertexAttribute { - private class Float1 : VertexAttribute + private class Float1(AttributeType attribute) : VertexAttribute(attribute) { - private readonly List _data = new(); - - public Float1(AttributeType attribute) : base(attribute) { } + private readonly List _data = []; public override int Count => _data.Count; diff --git a/CmodConvert/VertexAttribute.Float2.cs b/CmodConvert/VertexAttribute.Float2.cs index 20216f4..5c29c19 100644 --- a/CmodConvert/VertexAttribute.Float2.cs +++ b/CmodConvert/VertexAttribute.Float2.cs @@ -22,11 +22,9 @@ namespace CmodConvert; public abstract partial class VertexAttribute { - private class Float2 : VertexAttribute + private class Float2(AttributeType attribute) : VertexAttribute(attribute) { - private readonly List<(float, float)> _data = new(); - - public Float2(AttributeType attribute) : base(attribute) { } + private readonly List<(float, float)> _data = []; public override int Count => _data.Count; diff --git a/CmodConvert/VertexAttribute.Float3.cs b/CmodConvert/VertexAttribute.Float3.cs index 9e13670..2fe3056 100644 --- a/CmodConvert/VertexAttribute.Float3.cs +++ b/CmodConvert/VertexAttribute.Float3.cs @@ -22,11 +22,9 @@ namespace CmodConvert; public abstract partial class VertexAttribute { - private class Float3 : VertexAttribute + private class Float3(AttributeType attribute) : VertexAttribute(attribute) { - private readonly List<(float, float, float)> _data = new(); - - public Float3(AttributeType attribute) : base(attribute) { } + private readonly List<(float, float, float)> _data = []; public override int Count => _data.Count; diff --git a/CmodConvert/VertexAttribute.Float4.cs b/CmodConvert/VertexAttribute.Float4.cs index 0bd32fc..674f7ac 100644 --- a/CmodConvert/VertexAttribute.Float4.cs +++ b/CmodConvert/VertexAttribute.Float4.cs @@ -22,11 +22,9 @@ namespace CmodConvert; public abstract partial class VertexAttribute { - private class Float4 : VertexAttribute + private class Float4(AttributeType attribute) : VertexAttribute(attribute) { - private readonly List<(float, float, float, float)> _data = new(); - - public Float4(AttributeType attribute) : base(attribute) { } + private readonly List<(float, float, float, float)> _data = []; public override int Count => _data.Count; diff --git a/CmodConvert/VertexAttribute.UByte4.cs b/CmodConvert/VertexAttribute.UByte4.cs index 9b3a41f..06e2118 100644 --- a/CmodConvert/VertexAttribute.UByte4.cs +++ b/CmodConvert/VertexAttribute.UByte4.cs @@ -22,11 +22,9 @@ namespace CmodConvert; public abstract partial class VertexAttribute { - private class UByte4 : VertexAttribute + private class UByte4(AttributeType attribute) : VertexAttribute(attribute) { - private readonly List<(byte, byte, byte, byte)> _data = new(); - - public UByte4(AttributeType attribute) : base(attribute) { } + private readonly List<(byte, byte, byte, byte)> _data = []; public override int Count => _data.Count; diff --git a/CmodConvert/Wavefront/ObjPrimitive.cs b/CmodConvert/Wavefront/ObjPrimitive.cs index 05ac28b..3abce9c 100644 --- a/CmodConvert/Wavefront/ObjPrimitive.cs +++ b/CmodConvert/Wavefront/ObjPrimitive.cs @@ -18,14 +18,8 @@ namespace CmodConvert.Wavefront; -public class ObjPrimitive +public class ObjPrimitive(PrimitiveCategory category, int capacity) { - public ObjPrimitive(PrimitiveCategory category, int capacity) - { - Category = category; - Vertices = new(capacity); - } - - public PrimitiveCategory Category { get; } - public List Vertices { get; } + public PrimitiveCategory Category { get; } = category; + public List Vertices { get; } = new(capacity); } diff --git a/CmodConvert/Wavefront/WavefrontMesh.cs b/CmodConvert/Wavefront/WavefrontMesh.cs index 1c75e55..828de2e 100644 --- a/CmodConvert/Wavefront/WavefrontMesh.cs +++ b/CmodConvert/Wavefront/WavefrontMesh.cs @@ -222,7 +222,7 @@ private static void ProcessPrimitives(Mesh mesh, Dictionary(); + primitiveGroup = []; primitiveGroups.Add(primitive.MaterialIndex, primitiveGroup); } diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..8bf3209 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,16 @@ + + + enable + enable + true + none + 0.2.0 + Andrew Tribick + © 2021–2023 Andrew Tribick + https://github.com/ajtribick/cmodconvert + git + 0.2.0.0 + 0.2.0.0 + true + + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..ddede19 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,12 @@ + + + true + + + + + + + + + diff --git a/README.md b/README.md index ae69176..28638f6 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ The application runs on the command line, taking the input cmod file as a first default, the .obj and .mtl files will be output to the same directory, this can be changed using the `--output-file` and `--output-mtl` options. For details, run with the `--help` option. -Building the application requires .NET 6.0. The supplied cross-platform binary requires the .NET -6.0 runtime to be installed. +Building the application requires .NET 8.0. The supplied cross-platform binary requires the .NET +8.0 runtime to be installed. Example usage: