Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Phys File Type, Added more M2 chunks (some unfinished), changed some smaller things #11

Merged
merged 17 commits into from
Sep 22, 2024
27 changes: 26 additions & 1 deletion Warcraft.NET.Docs/ChunkAvailability.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ internal static class ChunkAvailability
"M2", new()
{
"MD21",
"PFID",
"SFID",
"AFID",
"BFID",
Expand Down Expand Up @@ -136,6 +135,32 @@ internal static class ChunkAvailability
}
},
}
},{
"phys", new ()
{
{
"PHYS", new()
{
"PHYS",
"PHYT",
"BDY4",
"SHP2",
"BOXS",
"CAPS",
"SPHS",
"PLYT",
"JOIN",
"WLJ3",
"SPHJ",
"SHJ2",
"PRS2",
"REV2",
"DSTJ",
"SHOJ",
"PHYV",
}
},
}
},
{
"tex", new ()
Expand Down
1 change: 1 addition & 0 deletions Warcraft.NET.Docs/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Warcraft.NET.Docs.Steps;
using Warcraft.NET.Files.Skel;

namespace Warcraft.NET.Docs
{
Expand Down
140 changes: 101 additions & 39 deletions Warcraft.NET/Extensions/ExtendedIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using Warcraft.NET.Exceptions;
using Warcraft.NET.Files.Interfaces;
Expand Down Expand Up @@ -78,6 +79,22 @@ public static Vector3 ReadVector3(this BinaryReader binaryReader, AxisConfigurat
}
}

/// <summary>
/// Reads a 48-byte <see cref="Mat3x4"/> structure from the data stream and advances the position of the stream by
/// 48 bytes.
/// </summary>
/// <returns>The Mat3x4.</returns>
/// <param name="binaryReader">The reader.</param>
/// <param name="convertTo">Which axis configuration the read mat3x4 should be converted to.</param>
public static Matrix3x4 ReadMatrix3x4(this BinaryReader binaryReader, AxisConfiguration convertTo = AxisConfiguration.YUp)
{
var a = binaryReader.ReadVector3(convertTo);
var b = binaryReader.ReadVector3(convertTo);
var c = binaryReader.ReadVector3(convertTo);
var pos = binaryReader.ReadVector3(convertTo);
return new Matrix3x4(a, b, c, pos);
}

/// <summary>
/// Reads a 12-byte <see cref="Rotator"/> from the data stream and advances the position of the stream by
/// 12 bytes.
Expand Down Expand Up @@ -283,37 +300,37 @@ public static ShortVector3 ReadShortVector3(this BinaryReader binaryReader, Axis
switch (convertTo)
{
case AxisConfiguration.Native:
{
return new ShortVector3(binaryReader.ReadInt16(), binaryReader.ReadInt16(), binaryReader.ReadInt16());
}
{
return new ShortVector3(binaryReader.ReadInt16(), binaryReader.ReadInt16(), binaryReader.ReadInt16());
}
case AxisConfiguration.YUp:
{
var x1 = binaryReader.ReadInt16();
var y1 = binaryReader.ReadInt16();
var z1 = binaryReader.ReadInt16();
{
var x1 = binaryReader.ReadInt16();
var y1 = binaryReader.ReadInt16();
var z1 = binaryReader.ReadInt16();

var x = x1;
var y = z1;
var z = (short)-y1;
var x = x1;
var y = z1;
var z = (short)-y1;

return new ShortVector3(x, y, z);
}
return new ShortVector3(x, y, z);
}
case AxisConfiguration.ZUp:
{
var x1 = binaryReader.ReadInt16();
var y1 = binaryReader.ReadInt16();
var z1 = binaryReader.ReadInt16();
{
var x1 = binaryReader.ReadInt16();
var y1 = binaryReader.ReadInt16();
var z1 = binaryReader.ReadInt16();

var x = x1;
var y = (short)-z1;
var z = y1;
var x = x1;
var y = (short)-z1;
var z = y1;

return new ShortVector3(x, y, z);
}
return new ShortVector3(x, y, z);
}
default:
{
throw new ArgumentOutOfRangeException(nameof(convertTo), convertTo, null);
}
{
throw new ArgumentOutOfRangeException(nameof(convertTo), convertTo, null);
}
}
}

Expand Down Expand Up @@ -432,6 +449,32 @@ public static void WriteChunkSignature(this BinaryWriter binaryWriter, string si
}
}

/// <summary>
/// Writes a struct to the BinaryWriter.
/// </summary>
/// <typeparam name="T">The type of struct to write.</typeparam>
/// <param name="binaryWriter">The BinaryWriter instance.</param>
/// <param name="value">The struct value to write.</param>
public static void WriteStruct<T>(this BinaryWriter binaryWriter, T value) where T : struct
{
int size = Marshal.SizeOf<T>();
byte[] bytes = new byte[size];

IntPtr ptr = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(value, ptr, true);
Marshal.Copy(ptr, bytes, 0, size);
}
finally
{
Marshal.FreeHGlobal(ptr);
}

// Write the padded bytes
binaryWriter.Write(bytes);
}

/// <summary>
/// Writes a 12-byte <see cref="Rotator"/> value to the data stream in Pitch/Yaw/Roll order.
/// </summary>
Expand Down Expand Up @@ -560,6 +603,25 @@ public static void WriteVector3(this BinaryWriter binaryWriter, Vector3 vector,
}
}

/// <summary>
/// Writes a 48-byte <see cref="Matrix3x4"/> value to the data stream. This function
/// </summary>
/// <param name="binaryWriter">The current <see cref="BinaryWriter"/> object.</param>
/// <param name="matrix">The Vector to write.</param>
/// <param name="storeAs">Which axis configuration the read vector should be stored as.</param>
public static void WriteMatrix3x4(this BinaryWriter binaryWriter, Matrix3x4 matrix, AxisConfiguration storeAs = AxisConfiguration.ZUp)
{
var column1 = matrix.RotationX * matrix.Scale.X;
var column2 = matrix.RotationY * matrix.Scale.Y;
var column3 = matrix.RotationZ * matrix.Scale.Z;
var column4 = matrix.Position;

binaryWriter.WriteVector3(column1, storeAs);
binaryWriter.WriteVector3(column2, storeAs);
binaryWriter.WriteVector3(column3, storeAs);
binaryWriter.WriteVector3(column4, storeAs);
}

/// <summary>
/// Writes a 16-byte <see cref="Quaternion"/> to the data stream.
/// </summary>
Expand Down Expand Up @@ -597,23 +659,23 @@ public static void WriteShortVector3(this BinaryWriter binaryWriter, ShortVector
{
case AxisConfiguration.Native:
case AxisConfiguration.YUp:
{
binaryWriter.Write(vector.X);
binaryWriter.Write(vector.Y);
binaryWriter.Write(vector.Z);
break;
}
{
binaryWriter.Write(vector.X);
binaryWriter.Write(vector.Y);
binaryWriter.Write(vector.Z);
break;
}
case AxisConfiguration.ZUp:
{
binaryWriter.Write(vector.X);
binaryWriter.Write((short)(vector.Z * -1));
binaryWriter.Write(vector.Y);
break;
}
{
binaryWriter.Write(vector.X);
binaryWriter.Write((short)(vector.Z * -1));
binaryWriter.Write(vector.Y);
break;
}
default:
{
throw new ArgumentOutOfRangeException(nameof(storeAs), storeAs, null);
}
{
throw new ArgumentOutOfRangeException(nameof(storeAs), storeAs, null);
}
}
}

Expand Down
69 changes: 69 additions & 0 deletions Warcraft.NET/Files/M2/Chunks/BfA/LDV1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.IO;
using Warcraft.NET.Attribute;
using Warcraft.NET.Files.Interfaces;
using Warcraft.NET.Files.M2.Entries;

namespace Warcraft.NET.Files.M2.Chunks.BfA
{
[AutoDocChunk(AutoDocChunkVersionHelper.VersionAfterLegion, AutoDocChunkVersionHelper.VersionBeforeBfA)]
public class LDV1 : IIFFChunk, IBinarySerializable
{
/// <summary>
/// Holds the binary chunk signature.
/// </summary>
public const string Signature = "LDV1";

/// <summary>
/// Gets or sets the Lod Data Version 1 Entries
/// </summary>
public List<LDV1Entry> LDV1Entries = new();

/// <summary>
/// Initializes a new instance of <see cref="LDV1"/>
/// </summary>
public LDV1() { }

/// <summary>
/// Initializes a new instance of <see cref="LDV1"/>
/// </summary>
/// <param name="inData">ExtendedData.</param>
public LDV1(byte[] inData) => LoadBinaryData(inData);

/// <inheritdoc />
public string GetSignature() { return Signature; }

/// <inheritdoc />
public uint GetSize() { return (uint)Serialize().Length; }

/// <inheritdoc />
public void LoadBinaryData(byte[] inData)
{
{
using (var ms = new MemoryStream(inData))
using (var br = new BinaryReader(ms))
{
var LDV1count = br.BaseStream.Length / LDV1Entry.GetSize();
for (var i = 0; i < LDV1count; ++i)
{
LDV1Entries.Add(new LDV1Entry(br.ReadBytes(LDV1Entry.GetSize())));
}
}
}
}

/// <inheritdoc />
public byte[] Serialize(long offset = 0)
{
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
foreach (LDV1Entry obj in LDV1Entries)
{
bw.Write(obj.Serialize());
}
return ms.ToArray();
}
}
}
}
2 changes: 1 addition & 1 deletion Warcraft.NET/Files/M2/Chunks/BfA/TXID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ public byte[] Serialize(long offset = 0)
}
}
}
}
}
51 changes: 51 additions & 0 deletions Warcraft.NET/Files/M2/Chunks/BfA/WFV1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.IO;
using Warcraft.NET.Attribute;
using Warcraft.NET.Files.Interfaces;
using Warcraft.NET.Files.M2.Entries;

namespace Warcraft.NET.Files.M2.Chunks.BfA
{
[AutoDocChunk(AutoDocChunkVersionHelper.VersionAfterLegion, AutoDocChunkVersionHelper.VersionBeforeBfA)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the parsing of the chunk struct is not implemented we dont add the AutoDocChunk.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove
[AutoDocChunk(AutoDocChunkVersionHelper.VersionAfterLegion, AutoDocChunkVersionHelper.VersionBeforeBfA)]

public class WFV1 : IIFFChunk, IBinarySerializable
{
/// <summary>
/// Holds the binary chunk signature.
/// </summary>
public const string Signature = "WFV1";

/// <summary>
/// Gets or sets the full data (deserialization NYI)
/// </summary>
public byte[] Data;

/// <summary>
/// Initializes a new instance of <see cref="WFV1"/>
/// </summary>
public WFV1() { }

/// <summary>
/// Initializes a new instance of <see cref="WFV1"/>
/// </summary>
/// <param name="inData">ExtendedData.</param>
public WFV1(byte[] inData) => LoadBinaryData(inData);

/// <inheritdoc />
public string GetSignature() { return Signature; }

/// <inheritdoc />
public uint GetSize() { return (uint)Serialize().Length; }

/// <inheritdoc />
public void LoadBinaryData(byte[] inData)
{
Data = inData;
}

/// <inheritdoc />
public byte[] Serialize(long offset = 0)
{
return Data;
}
}
}
Loading
Loading