Skip to content

Commit

Permalink
Collision: use enum for flags
Browse files Browse the repository at this point in the history
  • Loading branch information
hyperbx committed Aug 10, 2024
1 parent bc841c6 commit 005a910
Showing 1 changed file with 55 additions and 17 deletions.
72 changes: 55 additions & 17 deletions Marathon/Formats/Mesh/Collision.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Assimp;
using Assimp.Configs;
using System.Globalization;
using System.Xml.Linq;

namespace Marathon.Formats.Mesh
{
Expand Down Expand Up @@ -81,7 +83,7 @@ public override void Load(Stream stream)

reader.FixPadding();

face.Flags = reader.ReadUInt32(); // TODO: Experiment with flags to see what they all do.
face.Flags = (CollisionFlag)reader.ReadUInt32(); // TODO: Experiment with flags to see what they all do.

Data.Faces.Add(face);
}
Expand Down Expand Up @@ -115,7 +117,7 @@ public override void Save(Stream stream)
writer.Write(Data.Faces[i].VertexB);
writer.Write(Data.Faces[i].VertexC);
writer.FixPadding();
writer.Write(Data.Faces[i].Flags);
writer.Write((uint)Data.Faces[i].Flags);
}

writer.FinishWrite();
Expand All @@ -124,30 +126,30 @@ public override void Save(Stream stream)
public void ExportOBJ(string filePath)
{
// Create a SteamWriter.
StreamWriter obj = new(filePath);
var obj = new StreamWriter(filePath);

// Vertices.
foreach (Vector3 vertex in Data.Vertices)
obj.WriteLine($"v {vertex.X} {vertex.Y} {vertex.Z}");

// Faces.
// Get all used flags.
List<uint> Flags = new();
var flags = new List<CollisionFlag>();

foreach (CollisionFace face in Data.Faces)
{
if (!Flags.Contains(face.Flags))
Flags.Add(face.Flags);
if (!flags.Contains(face.Flags))
flags.Add(face.Flags);
}

// Write Faces.
foreach (uint Flag in Flags)
foreach (uint flag in flags)
{
obj.WriteLine($"\ng {Flag.ToString("x").PadLeft(8, '0')}");
obj.WriteLine($"\ng {flag.ToString("x").PadLeft(8, '0')}");

foreach (CollisionFace face in Data.Faces)
{
if (face.Flags == Flag)
if ((uint)face.Flags == flag)
obj.WriteLine($"f {face.VertexA + 1} {face.VertexB + 1} {face.VertexC + 1}");
}
}
Expand Down Expand Up @@ -179,12 +181,14 @@ public void ImportAssimp(string filePath)
name = name.Substring(1);

// Try read an @ sign for backwards compatibility.
if (name.Contains("@"))
try { meshNameTag = (uint)Convert.ToInt32(name.Substring(name.LastIndexOf('@') + 1), 16); } catch { }

// Try read the mesh name as the tag instead, leave it at 0 if it's not valid.
if (name.Contains('@'))
{
meshNameTag = ParseFlags(name[(name.LastIndexOf('@') + 1)..]);
}
else
try { meshNameTag = (uint)Convert.ToInt32(name, 16); } catch { }
{
meshNameTag = ParseFlags(name);
}

// Faces.
foreach (Face assimpFace in assimpMesh.Faces)
Expand All @@ -194,7 +198,7 @@ public void ImportAssimp(string filePath)
VertexA = (ushort)(assimpFace.Indices[0] + Data.Vertices.Count),
VertexB = (ushort)(assimpFace.Indices[1] + Data.Vertices.Count),
VertexC = (ushort)(assimpFace.Indices[2] + Data.Vertices.Count),
Flags = meshNameTag
Flags = (CollisionFlag)meshNameTag
};

Data.Faces.Add(face);
Expand All @@ -205,6 +209,14 @@ public void ImportAssimp(string filePath)
Data.Vertices.Add(new Vector3(assimpVertex.X, assimpVertex.Y, assimpVertex.Z));
}
}

private uint ParseFlags(string in_str)
{
if (uint.TryParse(in_str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var out_flags))
return out_flags;

return 0;
}
}

public class CollisionFace
Expand All @@ -215,11 +227,11 @@ public class CollisionFace

public ushort VertexC { get; set; }

public uint Flags { get; set; }
public CollisionFlag Flags { get; set; }

public CollisionFace() { }

public CollisionFace(ushort in_vertexA, ushort in_vertexB, ushort in_vertexC, uint in_flags)
public CollisionFace(ushort in_vertexA, ushort in_vertexB, ushort in_vertexC, CollisionFlag in_flags)
{
VertexA = in_vertexA;
VertexB = in_vertexB;
Expand All @@ -229,4 +241,30 @@ public CollisionFace(ushort in_vertexA, ushort in_vertexB, ushort in_vertexC, ui

public override string ToString() => $"<{VertexA}, {VertexB}, {VertexC}> @{Flags.ToString("X").PadLeft(8, '0')}";
}

public enum CollisionFlag : uint
{
Concrete = 0x00000000,
Water = 0x00000001,
Wood = 0x00000002,
Metal = 0x00000003,
Grass = 0x00000005,
Sand = 0x00000006,
Snow = 0x00000008,
Dirt = 0x00000009,
Glass = 0x0000000A,
MetalEcho = 0x0000000E,
Wall = 0x00010000,
NoStand = 0x00040000,
WaterSurface = 0x00080000,
Death = 0x00100000,
PlayerOnly = 0x00200000,
CameraOnly = 0x04000000,
Tentative = 0x10000000,
CornerDamage = 0x20000000,
Damage = 0x28000000,
WaterSurface2 = 0x40000000,
DeadlyWater = 0x60000000,
Climbable = 0x80000000
}
}

0 comments on commit 005a910

Please sign in to comment.