Skip to content

Commit

Permalink
Rework sections to match DOS2/BG3 layout
Browse files Browse the repository at this point in the history
  • Loading branch information
Norbyte committed Jul 13, 2023
1 parent 8a5ac05 commit 478e6a7
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 50 deletions.
13 changes: 5 additions & 8 deletions LSLib/Granny/GR2/Format.cs
Original file line number Diff line number Diff line change
Expand Up @@ -521,14 +521,11 @@ public UInt32 CalculateCRC(Stream stream)
public enum SectionType : uint
{
Main = 0,
RigidVertex = 1,
RigidIndex = 2,
DeformableVertex = 3,
DeformableIndex = 4,
Texture = 5,
Discardable = 6,
Unloaded = 7,
Max = Unloaded,
TrackGroup = 1,
Skeleton = 2,
Mesh = 3,
CurveAndDiscardable = 4,
FirstVertexData = 5,
Invalid = 0xffffffff
};

Expand Down
34 changes: 25 additions & 9 deletions LSLib/Granny/GR2/Writer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ public byte[] Write(object root, uint numCustomSections = 0)

foreach (var defn in Types.Values)
{
Sections[(int)SectionType.Discardable].WriteStructDefinition(defn);
Sections[(int)SectionType.CurveAndDiscardable].WriteStructDefinition(defn);
}

// We need to do this again to flush strings written by WriteMemberDefinition()
Expand Down Expand Up @@ -894,7 +894,7 @@ private void WriteMagic(Magic magic)
Writer.Write(magic.reserved2);
}

private Header InitHeader()
private Header InitHeader(uint numCustomSections)
{
var header = new Header();
header.version = Header.Version;
Expand All @@ -903,7 +903,7 @@ private Header InitHeader()
header.sectionsOffset = header.Size();
header.rootType = new SectionReference(); // Updated after serialization is finished
header.rootNode = new SectionReference(); // Updated after serialization is finished
header.numSections = (UInt32)SectionType.Max + 1;
header.numSections = (UInt32)SectionType.FirstVertexData + numCustomSections;
header.tag = VersionTag;
header.extraTags = new UInt32[Header.ExtraTagCount];
for (int i = 0; i < Header.ExtraTagCount; i++)
Expand Down Expand Up @@ -994,9 +994,19 @@ internal void QueueStructWrite(SectionType section, bool dataArea, MemberDefinit
serialization.section = section;
serialization.dataArea = dataArea;
if (member.PreferredSection != SectionType.Invalid)
{
serialization.section = member.PreferredSection;
else if (member.SectionSelector != null)
serialization.section = member.SectionSelector.SelectSection(member, type, obj);
}

if (member.SectionSelector != null)
{
var selectedSection = member.SectionSelector.SelectSection(member, type, obj);
if (selectedSection != SectionType.Invalid)
{
serialization.section = selectedSection;
}
}

serialization.type = type;
serialization.member = member;
serialization.obj = obj;
Expand All @@ -1010,10 +1020,16 @@ internal void QueueArrayWrite(SectionType section, bool dataArea, Type elementTy
QueuedArraySerialization serialization;
serialization.section = section;
serialization.dataArea = dataArea;
if (member.PreferredSection != SectionType.Invalid)
serialization.section = member.PreferredSection;
else if (member.SectionSelector != null)
serialization.section = member.SectionSelector.SelectSection(member, elementType, list);

if (member.SectionSelector != null)
{
var selectedSection = member.SectionSelector.SelectSection(member, elementType, list);
if (selectedSection != SectionType.Invalid)
{
serialization.section = selectedSection;
}
}

serialization.elementType = elementType;
serialization.member = member;
serialization.list = list;
Expand Down
2 changes: 1 addition & 1 deletion LSLib/Granny/Model/Animation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static float Dot(Quaternion r, Quaternion q)

public class AnimationCurve
{
[Serialization(TypeSelector = typeof(AnimationCurveDataTypeSelector), Type = MemberType.VariantReference, MinVersion = 0x80000011)]
[Serialization(Section = SectionType.CurveAndDiscardable, TypeSelector = typeof(AnimationCurveDataTypeSelector), Type = MemberType.VariantReference, MinVersion = 0x80000011)]
public AnimationCurveData CurveData;
[Serialization(MaxVersion = 0x80000010)]
public Int32 Degree;
Expand Down
2 changes: 1 addition & 1 deletion LSLib/Granny/Model/Exporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private void SaveGR2(string outPath, Root root)
writer.VersionTag -= 1;
}

var body = writer.Write(root);
var body = writer.Write(root, (root.Meshes != null) ? (uint)root.Meshes.Count : 0);
writer.Dispose();

FileStream f = File.Open(outPath, FileMode.Create, System.IO.FileAccess.Write, FileShare.None);
Expand Down
65 changes: 52 additions & 13 deletions LSLib/Granny/Model/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,24 @@ public class VertexAnnotationSet
public List<TriIndex> VertexAnnotationIndices;
}

public class VertexDataSectionSelector : SectionSelector
{
public SectionType SelectSection(MemberDefinition member, Type type, object obj)
{
if (obj is VertexData)
{
return ((VertexData)obj).SerializationSection;
}
else
{
return SectionType.Invalid;
}
}
}

public class VertexData
{
[Serialization(Type = MemberType.ReferenceToVariantArray, SectionSelector = typeof(VertexSerializer),
[Serialization(Type = MemberType.ReferenceToVariantArray,
TypeSelector = typeof(VertexSerializer), Serializer = typeof(VertexSerializer),
Kind = SerializationKind.UserElement)]
public List<Vertex> Vertices;
Expand All @@ -182,6 +197,9 @@ public class VertexData
[Serialization(Kind = SerializationKind.None)]
public VertexDeduplicator Deduplicator;

[Serialization(Kind = SerializationKind.None)]
public SectionType SerializationSection = SectionType.Invalid;

public void PostLoad()
{
// Fix missing vertex component names
Expand Down Expand Up @@ -382,33 +400,51 @@ public class TriAnnotationSet
[Serialization(Type = MemberType.ReferenceToVariantArray)]
public object TriAnnotations;
public Int32 IndicesMapFromTriToAnnotation;
[Serialization(Section = SectionType.RigidIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> TriAnnotationIndices;
}

public class TriTopologySectionSelector : SectionSelector
{
public SectionType SelectSection(MemberDefinition member, Type type, object obj)
{
if (obj is TriTopology)
{
return ((TriTopology)obj).SerializationSection;
}
else
{
return SectionType.Invalid;
}
}
}

public class TriTopology
{
public List<TriTopologyGroup> Groups;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> Indices;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex16), Kind = SerializationKind.UserMember, Serializer = typeof(UInt16ListSerializer))]
[Serialization(Prototype = typeof(TriIndex16), Kind = SerializationKind.UserMember, Serializer = typeof(UInt16ListSerializer))]
public List<UInt16> Indices16;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> VertexToVertexMap;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> VertexToTriangleMap;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> SideToNeighborMap;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer), MinVersion = 0x80000038)]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer), MinVersion = 0x80000038)]
public List<Int32> PolygonIndexStarts;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer), MinVersion = 0x80000038)]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer), MinVersion = 0x80000038)]
public List<Int32> PolygonIndices;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> BonesForTriangle;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> TriangleToBoneIndices;
public List<TriAnnotationSet> TriAnnotationSets;


[Serialization(Kind = SerializationKind.None)]
public SectionType SerializationSection = SectionType.Invalid;

public void ChangeWindingOrder()
{
if (Indices != null)
Expand Down Expand Up @@ -513,7 +549,7 @@ public class BoneBinding
public float[] OBBMin;
[Serialization(ArraySize = 3)]
public float[] OBBMax;
[Serialization(Section = SectionType.DeformableIndex, Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
[Serialization(Prototype = typeof(TriIndex), Kind = SerializationKind.UserMember, Serializer = typeof(Int32ListSerializer))]
public List<Int32> TriangleIndices;
}

Expand Down Expand Up @@ -578,15 +614,18 @@ public class MaterialBinding
public class MorphTarget
{
public string ScalarName;
[Serialization(SectionSelector = typeof(VertexDataSectionSelector))]
public VertexData VertexData;
public Int32 DataIsDeltas;
}

public class Mesh
{
public string Name;
[Serialization(SectionSelector = typeof(VertexDataSectionSelector))]
public VertexData PrimaryVertexData;
public List<MorphTarget> MorphTargets;
[Serialization(SectionSelector = typeof(TriTopologySectionSelector))]
public TriTopology PrimaryTopology;
[Serialization(DataArea = true)]
public List<MaterialBinding> MaterialBindings;
Expand Down
10 changes: 5 additions & 5 deletions LSLib/Granny/Model/Root.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ public class Root
public List<Texture> Textures;
[Serialization(Type = MemberType.ArrayOfReferences)]
public List<Material> Materials;
[Serialization(Type = MemberType.ArrayOfReferences)]
[Serialization(Section = SectionType.Skeleton, Type = MemberType.ArrayOfReferences)]
public List<Skeleton> Skeletons;
[Serialization(Type = MemberType.ArrayOfReferences)]
[Serialization(Type = MemberType.ArrayOfReferences, SectionSelector = typeof(VertexDataSectionSelector))]
public List<VertexData> VertexDatas;
[Serialization(Type = MemberType.ArrayOfReferences)]
[Serialization(Type = MemberType.ArrayOfReferences, SectionSelector = typeof(TriTopologySectionSelector))]
public List<TriTopology> TriTopologies;
[Serialization(Type = MemberType.ArrayOfReferences)]
[Serialization(Section = SectionType.Mesh, Type = MemberType.ArrayOfReferences)]
public List<Mesh> Meshes;
[Serialization(Type = MemberType.ArrayOfReferences)]
public List<Model> Models;
[Serialization(Type = MemberType.ArrayOfReferences)]
[Serialization(Section = SectionType.TrackGroup, Type = MemberType.ArrayOfReferences)]
public List<TrackGroup> TrackGroups;
[Serialization(Type = MemberType.ArrayOfReferences)]
public List<Animation> Animations;
Expand Down
14 changes: 1 addition & 13 deletions LSLib/Granny/Model/Vertex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,22 +409,10 @@ public void Unserialize(GR2Reader reader)
}


public class VertexSerializer : NodeSerializer, SectionSelector
public class VertexSerializer : NodeSerializer
{
private Dictionary<object, VertexDescriptor> VertexTypeCache = new Dictionary<object, VertexDescriptor>();

public SectionType SelectSection(MemberDefinition member, Type type, object obj)
{
var vertices = obj as List<Vertex>;
if (vertices == null || vertices.Count == 0)
return SectionType.RigidVertex;

if (vertices[0].Format.HasBoneWeights)
return SectionType.DeformableVertex;
else
return SectionType.RigidVertex;
}

public VertexDescriptor ConstructDescriptor(MemberDefinition memberDefn, StructDefinition defn, object parent)
{
var desc = new VertexDescriptor();
Expand Down

0 comments on commit 478e6a7

Please sign in to comment.