Skip to content

Commit 8dc13a3

Browse files
committed
CharCollide; rework compression; GH2 Sfx and RandomGroupSeq fixes
1 parent 43cdb88 commit 8dc13a3

5 files changed

Lines changed: 326 additions & 110 deletions

File tree

MiloLib/Assets/Char/CharCollide.cs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
using MiloLib.Assets.Rnd;
2+
using MiloLib.Classes;
3+
using MiloLib.Utils;
4+
5+
namespace MiloLib.Assets.Char
6+
{
7+
// this description will always sound very metal
8+
[Name("CharCollide"), Description("Feeds the bones when executed.")]
9+
public class CharCollide : Object
10+
{
11+
public enum Shape
12+
{
13+
kPlane = 0,
14+
kSphere = 1,
15+
kInsideSphere = 2,
16+
kCigar = 3,
17+
kInsideCigar = 4,
18+
};
19+
20+
public struct CharCollideStruct
21+
{
22+
public int unk0;
23+
public Vector3 vec;
24+
25+
public void Read(EndianReader reader)
26+
{
27+
unk0 = reader.ReadInt32();
28+
vec = new Vector3().Read(reader);
29+
}
30+
31+
public void Write(EndianWriter writer)
32+
{
33+
writer.WriteInt32(unk0);
34+
vec.Write(writer);
35+
}
36+
};
37+
38+
private ushort altRevision;
39+
private ushort revision;
40+
41+
public RndTrans trans = new();
42+
43+
[Name("Shape"), Description("Type of collision")]
44+
public Shape shape;
45+
46+
[Name("Radius0"), Description("Radius of the sphere, or of length0 hemisphere if cigar")]
47+
public float[] origRadius = new float[2] { 0, 0 };
48+
[Name("Length0"), Description("cigar: placement of radius0 hemisphere along X axis, must be < than length0, not used for sphere shapes")]
49+
public float[] origLength = new float[2] { 0, 0 };
50+
[Name("Radius1"), Description("cigar: Radius of length1 hemisphere")]
51+
public float[] curRadius = new float[2] { 0, 0 };
52+
[Name("Length1"), Description("cigar: placement of radius1 hemisphere along X axis, must be >= length0")]
53+
public float[] curLength = new float[2] { 0, 0 };
54+
55+
[MinVersion(2)]
56+
public int flags;
57+
58+
[MinVersion(6)]
59+
public Matrix unknownTransform = new();
60+
61+
[Name("Mesh"), Description("Optional mesh that will deform, used to resize ourselves. If this is set, make sure you are not parented to any bone with scale, such as an exo bone"), MinVersion(6)]
62+
public Symbol mesh = new(0, "");
63+
64+
[MinVersion(6)]
65+
public List<CharCollideStruct> structs = new(8);
66+
67+
[MinVersion(6)]
68+
public byte[] sha1Digest = new byte[20];
69+
70+
[Name("Mesh Y Bias"), Description("For spheres + cigars, finds mesh points along positive y axis (the green one), makes a better fit for spheres where only one side should be the fit, like for chest and back collision volumes"), MinVersion(6)]
71+
public bool meshYBias;
72+
73+
public CharCollide Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)
74+
{
75+
uint combinedRevision = reader.ReadUInt32();
76+
if (BitConverter.IsLittleEndian) (revision, altRevision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
77+
else (altRevision, revision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
78+
79+
base.Read(reader, false, parent, entry);
80+
trans.Read(reader, false, parent, entry);
81+
82+
shape = (Shape)reader.ReadUInt32();
83+
84+
origRadius[1] = reader.ReadFloat();
85+
86+
if (revision > 4)
87+
origLength[0] = reader.ReadFloat();
88+
if (revision > 2)
89+
origLength[1] = reader.ReadFloat();
90+
if (revision > 1)
91+
flags = reader.ReadInt32();
92+
if (revision > 3)
93+
curRadius[0] = reader.ReadFloat();
94+
95+
if (revision > 5)
96+
{
97+
origRadius[1] = reader.ReadFloat();
98+
curRadius[1] = reader.ReadFloat();
99+
curLength[0] = reader.ReadFloat();
100+
curLength[1] = reader.ReadFloat();
101+
unknownTransform.Read(reader);
102+
mesh = Symbol.Read(reader);
103+
for (int i = 0; i < 8; i++)
104+
{
105+
CharCollideStruct unkStruct = new CharCollideStruct();
106+
unkStruct.Read(reader);
107+
structs.Add(unkStruct);
108+
}
109+
110+
sha1Digest = reader.ReadBlock(20);
111+
meshYBias = reader.ReadBoolean();
112+
}
113+
if (standalone)
114+
if ((reader.Endianness == Endian.BigEndian ? 0xADDEADDE : 0xDEADDEAD) != reader.ReadUInt32()) throw new Exception("Got to end of standalone asset but didn't find the expected end bytes, read likely did not succeed");
115+
116+
return this;
117+
}
118+
119+
public override void Write(EndianWriter writer, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry? entry)
120+
{
121+
writer.WriteUInt32(BitConverter.IsLittleEndian ? (uint)((altRevision << 16) | revision) : (uint)((revision << 16) | altRevision));
122+
123+
base.Write(writer, false, parent, entry);
124+
trans.Write(writer, false, true);
125+
126+
writer.WriteUInt32((uint)shape);
127+
128+
writer.WriteFloat(origRadius[1]);
129+
130+
if (revision > 4)
131+
writer.WriteFloat(origLength[0]);
132+
if (revision > 2)
133+
writer.WriteFloat(origLength[1]);
134+
if (revision > 1)
135+
writer.WriteInt32(flags);
136+
if (revision > 3)
137+
writer.WriteFloat(curRadius[0]);
138+
139+
if (revision > 5)
140+
{
141+
writer.WriteFloat(origRadius[1]);
142+
writer.WriteFloat(curRadius[1]);
143+
writer.WriteFloat(curLength[0]);
144+
writer.WriteFloat(curLength[1]);
145+
unknownTransform.Write(writer);
146+
Symbol.Write(writer, mesh);
147+
foreach (var unkStruct in structs)
148+
{
149+
unkStruct.Write(writer);
150+
}
151+
writer.WriteBlock(sha1Digest);
152+
writer.WriteBoolean(meshYBias);
153+
}
154+
155+
if (standalone)
156+
writer.WriteBlock(new byte[4] { 0xAD, 0xDE, 0xAD, 0xDE });
157+
}
158+
159+
}
160+
}

MiloLib/Assets/DirectoryMeta.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,10 @@ public void ReadEntry(EndianReader reader, DirectoryMeta.Entry entry)
961961
Debug.WriteLine("Reading entry CharClipGroup " + entry.name.value);
962962
entry.obj = new CharClipGroup().Read(reader, true, this, entry);
963963
break;
964+
case "CharCollide":
965+
Debug.WriteLine("Reading entry CharCollide " + entry.name.value);
966+
entry.obj = new CharCollide().Read(reader, true, this, entry);
967+
break;
964968
case "CharForeTwist":
965969
Debug.WriteLine("Reading entry CharForeTwist " + entry.name.value);
966970
entry.obj = new CharForeTwist().Read(reader, true, this, entry);
@@ -1498,6 +1502,9 @@ public void WriteEntry(EndianWriter writer, DirectoryMeta.Entry entry)
14981502
case "CharClipGroup":
14991503
((CharClipGroup)entry.obj).Write(writer, true, this, entry);
15001504
break;
1505+
case "CharCollide":
1506+
((CharCollide)entry.obj).Write(writer, true, this, entry);
1507+
break;
15011508
case "CharForeTwist":
15021509
((CharForeTwist)entry.obj).Write(writer, true, this, entry);
15031510
break;

MiloLib/Assets/Synth/RandomGroupSeq.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class RandomGroupSeq : GroupSeq
1111

1212
[Name("Number of Simultaneous Sequences"), Description("Number of children to play simultaneously")]
1313
public uint numSimultaneous;
14-
[Name("Allow Repeats"), Description("If false, you will never hear the same sequence again until all have played (only if num_simul is 1)")]
14+
[Name("Allow Repeats"), Description("If false, you will never hear the same sequence again until all have played (only if num_simul is 1)"), MinVersion(2)]
1515
public bool allowRepeats;
1616

1717
public RandomGroupSeq Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)
@@ -23,7 +23,8 @@ public RandomGroupSeq Read(EndianReader reader, bool standalone, DirectoryMeta p
2323
base.Read(reader, false, parent, entry);
2424

2525
numSimultaneous = reader.ReadUInt32();
26-
allowRepeats = reader.ReadBoolean();
26+
if (revision >= 2)
27+
allowRepeats = reader.ReadBoolean();
2728

2829
if (standalone)
2930
if ((reader.Endianness == Endian.BigEndian ? 0xADDEADDE : 0xDEADDEAD) != reader.ReadUInt32()) throw new Exception("Got to end of standalone asset but didn't find the expected end bytes, read likely did not succeed");
@@ -38,7 +39,8 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p
3839
base.Write(writer, false, parent, entry);
3940

4041
writer.WriteUInt32(numSimultaneous);
41-
writer.WriteBoolean(allowRepeats);
42+
if (revision >= 2)
43+
writer.WriteBoolean(allowRepeats);
4244

4345
if (standalone)
4446
writer.WriteBlock(new byte[4] { 0xAD, 0xDE, 0xAD, 0xDE });

MiloLib/Assets/Synth/Sfx.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,18 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p
179179
}
180180

181181
if (4 < revision)
182+
{
182183
Symbol.Write(writer, sendObj);
184+
if (revision <= 7)
185+
{
186+
writer.WriteUInt32(unkInt1);
187+
}
188+
}
183189

184-
if (8 < revision)
190+
if (revision >= 9)
185191
faderGroup.Write(writer);
186192

187-
if (revision > 11)
193+
if (revision >= 11)
188194
{
189195
writer.WriteFloat(reverbMixDb);
190196
writer.WriteBoolean(reverbSendEnable);

0 commit comments

Comments
 (0)