Skip to content

Commit fe9d9ec

Browse files
authored
Merge pull request #123 from Dnawrkshp/feat/rc4-animations
Add support for DL animations
2 parents 6d9c70c + f1c94a5 commit fe9d9ec

5 files changed

Lines changed: 52 additions & 31 deletions

File tree

LibReplanetizer/Models/Animation/Animation.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,10 @@ private void GetDLVals(FileStream fs, GameType game, int modelOffset, int animat
109109
unk7 = header[0x13];
110110

111111
int offsetSound = ReadInt(header, 0x14);
112-
int offsetUnk = ReadInt(header, 0x18);
112+
int offsetAnimInfo = ReadInt(header, 0x18);
113113
int offsetFrameHeader = ReadInt(header, 0x1C);
114114

115-
byte[] unkBytes = ReadBlock(fs, modelOffset + animationOffset + offsetUnk, offsetFrameHeader - offsetUnk);
115+
byte[] animInfoBytes = ReadBlock(fs, modelOffset + animationOffset + offsetAnimInfo, offsetFrameHeader - offsetAnimInfo);
116116

117117
byte[] frameHeaderBlock = ReadBlock(fs, modelOffset + animationOffset + offsetFrameHeader, 0x10);
118118

@@ -135,6 +135,9 @@ private void GetDLVals(FileStream fs, GameType game, int modelOffset, int animat
135135
{
136136
sounds.Add(ReadInt(extrasBlock, i * 4));
137137
}
138+
139+
// speed is not stored in anim header
140+
speed = 1;
138141
}
139142

140143
public byte[] Serialize(int baseOffset = 0, int fileOffset = 0)

LibReplanetizer/Models/Animation/BoneData.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ private void GetDLVals(byte[] boneDataBlock, int num)
5858
unk0x0C = ReadShort(boneDataBlock, offset + 0x0C);
5959
parent = ReadShort(boneDataBlock, offset + 0x0E);
6060

61-
if (parent == 0xFF)
61+
if (parent == 0xFF || parent == 0x7F)
6262
{
63-
// The root node is always marked with 0xFF.
63+
// The root node is always marked with 0xFF/0x7F.
6464
parent = 0;
6565
}
6666
else

LibReplanetizer/Models/Animation/Frame.cs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,25 @@ public class Frame
1919

2020
private struct FrameBoneRotation
2121
{
22-
public FrameBoneRotation(int x, int y, int z, int w)
22+
public FrameBoneRotation(GameType game, int x, int y, int z, int w)
2323
{
24-
this.rotation = new Quaternion(x / 32767f, y / 32767f, z / 32767f, w / 32767f);
24+
if (game.num == 4)
25+
{
26+
this.rotation = new Quaternion(ParseDlFloat(x), ParseDlFloat(y), ParseDlFloat(z), -ParseDlFloat(w));
27+
}
28+
else
29+
{
30+
this.rotation = new Quaternion(x / 32767f, y / 32767f, z / 32767f, -w / 32767f);
31+
}
32+
}
33+
34+
private float ParseDlFloat(int v)
35+
{
36+
int vpos = v & 0x7fff;
37+
if (v < 0)
38+
return vpos / -32767f;
39+
40+
return vpos / 32767f;
2541
}
2642

2743
public Quaternion rotation;
@@ -115,7 +131,9 @@ public bool GetScalingUnk(int bone)
115131

116132
if (exists)
117133
{
118-
return translations.First(t => t.bone == bone).translation;
134+
// dl can have multiple translations per bone
135+
// doesn't seem to break the other rac games
136+
return translations.Where(t => t.bone == bone).Select(x => x.translation).Aggregate((a, b) => a + b);
119137
}
120138

121139
return null;
@@ -210,7 +228,7 @@ public Frame(FileStream fs, GameType game, int offset, int boneCount)
210228
int y = ReadShort(frameBlock, i * 8 + 0x02);
211229
int z = ReadShort(frameBlock, i * 8 + 0x04);
212230
int w = ReadShort(frameBlock, i * 8 + 0x06);
213-
rotations.Add(new FrameBoneRotation(x, y, z, -w));
231+
rotations.Add(new FrameBoneRotation(game, x, y, z, w));
214232
}
215233

216234
scalings = new List<FrameBoneScaling>();
@@ -249,13 +267,6 @@ public Frame(FileStream fs, GameType game, int offset, int boneCount)
249267
// Constructor for Deadlocked
250268
public Frame(byte[] frameBlock, int offset, int numRotations, int numScalings, int numTranslations)
251269
{
252-
// This code is not correct and is causing crashes.
253-
// TODO: (Milch) Implement support for Deadlocked animations.
254-
#if true
255-
rotations = new List<FrameBoneRotation>();
256-
scalings = new List<FrameBoneScaling>();
257-
translations = new List<FrameBoneTranslation>();
258-
#else
259270
int rotationOffset = 0;
260271
rotations = new List<FrameBoneRotation>();
261272
for (int i = 0; i < numRotations; i++)
@@ -265,16 +276,16 @@ public Frame(byte[] frameBlock, int offset, int numRotations, int numScalings, i
265276
int y = ReadShort(frameBlock, offset + i * 8 + 0x02);
266277
int z = ReadShort(frameBlock, offset + i * 8 + 0x04);
267278
int w = ReadShort(frameBlock, offset + i * 8 + 0x06);
268-
rotations.Add(new FrameBoneRotation(x, y, z, -w));
279+
rotations.Add(new FrameBoneRotation(GameType.DL, x, y, z, w));
269280
}
270281

271282
int scalingOffset = rotationOffset + numRotations * 0x08;
272283
scalings = new List<FrameBoneScaling>();
273284
for (int i = 0; i < numScalings; i++)
274285
{
275-
float x = ReadShort(frameBlock, offset + scalingOffset + i * 8 + 0x00) / 32767.0f;
276-
float y = ReadShort(frameBlock, offset + scalingOffset + i * 8 + 0x02) / 32767.0f;
277-
float z = ReadShort(frameBlock, offset + scalingOffset + i * 8 + 0x04) / 32767.0f;
286+
float x = ReadShort(frameBlock, offset + scalingOffset + i * 8 + 0x00) / 4096.0f;
287+
float y = ReadShort(frameBlock, offset + scalingOffset + i * 8 + 0x02) / 4096.0f;
288+
float z = ReadShort(frameBlock, offset + scalingOffset + i * 8 + 0x04) / 4096.0f;
278289
byte unk = frameBlock[offset + scalingOffset + i * 8 + 0x06];
279290
byte bone = frameBlock[offset + scalingOffset + i * 8 + 0x07];
280291
scalings.Add(new FrameBoneScaling(x, y, z, bone, unk));
@@ -284,14 +295,13 @@ public Frame(byte[] frameBlock, int offset, int numRotations, int numScalings, i
284295
translations = new List<FrameBoneTranslation>();
285296
for (int i = 0; i < numTranslations; i++)
286297
{
287-
float x = ReadShort(frameBlock, offset + translationOffset + i * 8 + 0x00) / 32767.0f;
288-
float y = ReadShort(frameBlock, offset + translationOffset + i * 8 + 0x02) / 32767.0f;
289-
float z = ReadShort(frameBlock, offset + translationOffset + i * 8 + 0x04) / 32767.0f;
298+
float x = ReadShort(frameBlock, offset + translationOffset + i * 8 + 0x00) / 1024.0f;
299+
float y = ReadShort(frameBlock, offset + translationOffset + i * 8 + 0x02) / 1024.0f;
300+
float z = ReadShort(frameBlock, offset + translationOffset + i * 8 + 0x04) / 1024.0f;
290301
byte unk = frameBlock[offset + translationOffset + i * 8 + 0x06];
291302
byte bone = frameBlock[offset + translationOffset + i * 8 + 0x07];
292303
translations.Add(new FrameBoneTranslation(x, y, z, bone, unk));
293304
}
294-
#endif
295305
}
296306

297307
public byte[] Serialize()

LibReplanetizer/Models/MobyModel.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,17 @@ public MobyModel(FileStream fs, GameType game, short modelID, int offset)
180180
color2 = ReadUint(headBlock, 0x40);
181181
unk6 = ReadUint(headBlock, 0x44);
182182

183+
// dynamically determine skeleton format
184+
// since rc4 actually has some rc3 models in it
185+
var skeletonGame = game;
186+
if (boneDataPointer > 0 && boneMatrixPointer > 0 && boneCount > 0)
187+
{
188+
if (((boneDataPointer - boneMatrixPointer) / boneCount) == 0x30)
189+
skeletonGame = GameType.DL;
190+
else
191+
skeletonGame = GameType.RaC3;
192+
}
193+
183194
// Animation block
184195
byte[] animationPointerBlock = ReadBlock(fs, offset + HEADERSIZE, animationCount * 0x04);
185196

@@ -224,7 +235,7 @@ public MobyModel(FileStream fs, GameType game, short modelID, int offset)
224235
byte[] boneMatrixBlock = ReadBlock(fs, offset + boneMatrixPointer, boneCount * 0x40);
225236
for (int i = 0; i < boneCount; i++)
226237
{
227-
boneMatrices.Add(new BoneMatrix(game, boneMatrixBlock, i));
238+
boneMatrices.Add(new BoneMatrix(skeletonGame, boneMatrixBlock, i));
228239
}
229240
}
230241

@@ -236,7 +247,7 @@ public MobyModel(FileStream fs, GameType game, short modelID, int offset)
236247
byte[] boneDataBlock = ReadBlock(fs, offset + boneDataPointer, boneCount * 0x10);
237248
for (int i = 0; i < boneCount; i++)
238249
{
239-
boneDatas.Add(new BoneData(game, boneDataBlock, i));
250+
boneDatas.Add(new BoneData(skeletonGame, boneDataBlock, i));
240251
}
241252
}
242253

Replanetizer/Frames/ModelFrame.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,7 @@ public override void Render(float deltaTime)
384384
// Collada specific settings
385385
if (exportSettings.format == ExporterModelSettings.Format.Collada)
386386
{
387-
// TODO: (Milch) Enable animations for Deadlocked once they are implemented.
388-
if (level.game != GameType.DL && selectedModel is MobyModel mobyModel && mobyModel.animations.Count > 0)
387+
if (selectedModel is MobyModel mobyModel && mobyModel.animations.Count > 0)
389388
{
390389
int animationChoice = (int) exportSettings.animationChoice;
391390
if (ImGui.Combo("Animations", ref animationChoice, ExporterModelSettings.ANIMATION_CHOICE_STRINGS, ExporterModelSettings.ANIMATION_CHOICE_STRINGS.Length - 1))
@@ -432,8 +431,7 @@ public override void Render(float deltaTime)
432431
// glTF specific settings
433432
if (exportSettings.format == ExporterModelSettings.Format.glTF)
434433
{
435-
// TODO: (Milch) Enable animations for Deadlocked once they are implemented.
436-
if (level.game != GameType.DL && selectedModel is MobyModel mobyModel && mobyModel.animations.Count > 0)
434+
if (selectedModel is MobyModel mobyModel && mobyModel.animations.Count > 0)
437435
{
438436
bool includeAnimations = (exportSettings.animationChoice != ExporterModelSettings.AnimationChoice.None);
439437

@@ -483,8 +481,7 @@ public override void Render(float deltaTime)
483481

484482
ImGui.Separator();
485483

486-
// TODO: (Milch) Enable animations for Deadlocked once they are implemented.
487-
if (level.game != GameType.DL && selectedModel is MobyModel mobModel && mobModel.animations.Count > 0)
484+
if (selectedModel is MobyModel mobModel && mobModel.animations.Count > 0)
488485
{
489486
ImGui.Checkbox("Show Animations", ref rendererPayload.visibility.enableAnimations);
490487

0 commit comments

Comments
 (0)