From 5733ee429700b66c1d081a502d140863b98bde4e Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Tue, 23 Apr 2024 06:46:16 +0100 Subject: [PATCH] Refactor model IO (#624) Part of #619. --- TRLevelControl/Build/TRModelBuilder.cs | 264 ++++++++++++++++++++ TRLevelControl/Control/TR1LevelControl.cs | 97 ++----- TRLevelControl/Control/TR2LevelControl.cs | 97 ++----- TRLevelControl/Control/TR3LevelControl.cs | 97 ++----- TRLevelControl/Control/TR4LevelControl.cs | 59 ++--- TRLevelControl/Control/TR5LevelControl.cs | 59 ++--- TRLevelControl/IO/TRLevelReader.cs | 9 + TRLevelControl/IO/TRLevelWriter.cs | 6 + TRLevelControl/Model/Base/TRAnimCommand.cs | 14 +- TRLevelControl/Model/Base/TRAnimDispatch.cs | 17 +- TRLevelControl/Model/Base/TRAnimation.cs | 36 +-- TRLevelControl/Model/Base/TRMeshTreeNode.cs | 17 +- TRLevelControl/Model/Base/TRModel.cs | 19 +- TRLevelControl/Model/Base/TRStateChange.cs | 16 +- TRLevelControl/Model/TR4/TR4Animation.cs | 66 ----- TRLevelControl/Model/TR4/TR4Level.cs | 2 +- TRLevelControl/Model/TR5/TR5Level.cs | 4 +- TRLevelControl/Model/TR5/TR5Model.cs | 52 ---- TRLevelControl/TR2FileReadUtilities.cs | 82 ------ TRLevelControl/TR4FileReadUtilities.cs | 101 -------- TRLevelControl/TR5FileReadUtilities.cs | 76 ------ 21 files changed, 404 insertions(+), 786 deletions(-) create mode 100644 TRLevelControl/Build/TRModelBuilder.cs delete mode 100644 TRLevelControl/Model/TR4/TR4Animation.cs delete mode 100644 TRLevelControl/Model/TR5/TR5Model.cs diff --git a/TRLevelControl/Build/TRModelBuilder.cs b/TRLevelControl/Build/TRModelBuilder.cs new file mode 100644 index 000000000..a5facb22e --- /dev/null +++ b/TRLevelControl/Build/TRModelBuilder.cs @@ -0,0 +1,264 @@ +using System.Diagnostics; +using TRLevelControl.Model; + +namespace TRLevelControl.Build; + +public class TRModelBuilder +{ + private static readonly ushort _tr5ModelPadding = 0xFFEF; + + private readonly TRGameVersion _version; + + public TRModelBuilder(TRGameVersion version) + { + _version = version; + } + + public List ReadAnimations(TRLevelReader reader) + { + uint numAnimations = reader.ReadUInt32(); + List animations = new(); + + for (int i = 0; i < numAnimations; i++) + { + TRAnimation animation = new() + { + FrameOffset = reader.ReadUInt32(), + FrameRate = reader.ReadByte(), + FrameSize = reader.ReadByte(), + StateID = reader.ReadUInt16(), + Speed = reader.ReadFixed32(), + Accel = reader.ReadFixed32(), + }; + + if (_version >= TRGameVersion.TR4) + { + animation.SpeedLateral = reader.ReadFixed32(); + animation.AccelLateral = reader.ReadFixed32(); + } + + animation.FrameStart = reader.ReadUInt16(); + animation.FrameEnd = reader.ReadUInt16(); + animation.NextAnimation = reader.ReadUInt16(); + animation.NextFrame = reader.ReadUInt16(); + animation.NumStateChanges = reader.ReadUInt16(); + animation.StateChangeOffset = reader.ReadUInt16(); + animation.NumAnimCommands = reader.ReadUInt16(); + animation.AnimCommand = reader.ReadUInt16(); + + animations.Add(animation); + } + + return animations; + } + + public void Write(List animations, TRLevelWriter writer) + { + writer.Write((uint)animations.Count); + + foreach (TRAnimation animation in animations) + { + writer.Write(animation.FrameOffset); + writer.Write(animation.FrameRate); + writer.Write(animation.FrameSize); + writer.Write(animation.StateID); + writer.Write(animation.Speed); + writer.Write(animation.Accel); + + if (_version >= TRGameVersion.TR4) + { + writer.Write(animation.SpeedLateral); + writer.Write(animation.AccelLateral); + } + + writer.Write(animation.FrameStart); + writer.Write(animation.FrameEnd); + writer.Write(animation.NextAnimation); + writer.Write(animation.NextFrame); + writer.Write(animation.NumStateChanges); + writer.Write(animation.StateChangeOffset); + writer.Write(animation.NumAnimCommands); + writer.Write(animation.AnimCommand); + } + } + + public List ReadStateChanges(TRLevelReader reader) + { + uint numStateChanges = reader.ReadUInt32(); + List stateChanges = new(); + + for (int i = 0; i < numStateChanges; i++) + { + stateChanges.Add(new() + { + StateID = reader.ReadUInt16(), + NumAnimDispatches = reader.ReadUInt16(), + AnimDispatch = reader.ReadUInt16(), + }); + } + + return stateChanges; + } + + public void Write(List stateChanges, TRLevelWriter writer) + { + writer.Write((uint)stateChanges.Count); + + foreach (TRStateChange stateChange in stateChanges) + { + writer.Write(stateChange.StateID); + writer.Write(stateChange.NumAnimDispatches); + writer.Write(stateChange.AnimDispatch); + } + } + + public List ReadDispatches(TRLevelReader reader) + { + uint numAnimDispatches = reader.ReadUInt32(); + List dispatches = new(); + + for (int i = 0; i < numAnimDispatches; i++) + { + dispatches.Add(new() + { + Low = reader.ReadInt16(), + High = reader.ReadInt16(), + NextAnimation = reader.ReadInt16(), + NextFrame = reader.ReadInt16(), + }); + } + + return dispatches; + } + + public void Write(List dispatches, TRLevelWriter writer) + { + writer.Write((uint)dispatches.Count); + + foreach (TRAnimDispatch dispatch in dispatches) + { + writer.Write(dispatch.Low); + writer.Write(dispatch.High); + writer.Write(dispatch.NextAnimation); + writer.Write(dispatch.NextFrame); + } + } + + public List ReadCommands(TRLevelReader reader) + { + uint numAnimCommands = reader.ReadUInt32(); + List commands = new(); + + for (int i = 0; i < numAnimCommands; i++) + { + commands.Add(new() + { + Value = reader.ReadInt16(), + }); + } + + return commands; + } + + public void Write(List commands, TRLevelWriter writer) + { + writer.Write((uint)commands.Count); + + foreach (TRAnimCommand command in commands) + { + writer.Write(command.Value); + } + } + + public List ReadTrees(TRLevelReader reader) + { + uint numMeshTrees = reader.ReadUInt32() / sizeof(int); + List trees = new(); + + for (int i = 0; i < numMeshTrees; i++) + { + trees.Add(new() + { + Flags = reader.ReadUInt32(), + OffsetX = reader.ReadInt32(), + OffsetY = reader.ReadInt32(), + OffsetZ = reader.ReadInt32(), + }); + } + + return trees; + } + + public void Write(List trees, TRLevelWriter writer) + { + writer.Write((uint)trees.Count * sizeof(int)); + + foreach (TRMeshTreeNode tree in trees) + { + writer.Write(tree.Flags); + writer.Write(tree.OffsetX); + writer.Write(tree.OffsetY); + writer.Write(tree.OffsetZ); + } + } + + public List ReadFrames(TRLevelReader reader) + { + uint numFrames = reader.ReadUInt32(); + return new(reader.ReadUInt16s(numFrames)); + } + + public void Write(List frames, TRLevelWriter writer) + { + writer.Write((uint)frames.Count); + writer.Write(frames); + } + + public List ReadModels(TRLevelReader reader) + { + uint numModels = reader.ReadUInt32(); + List models = new(); + + for (int i = 0; i < numModels; i++) + { + TRModel model = new() + { + ID = reader.ReadUInt32(), + NumMeshes = reader.ReadUInt16(), + StartingMesh = reader.ReadUInt16(), + MeshTree = reader.ReadUInt32(), + FrameOffset = reader.ReadUInt32(), + Animation = reader.ReadUInt16() + }; + + if (_version == TRGameVersion.TR5) + { + Debug.Assert(reader.ReadUInt16() == _tr5ModelPadding); + } + + models.Add(model); + } + + return models; + } + + public void Write(List models, TRLevelWriter writer) + { + writer.Write((uint)models.Count); + + foreach (TRModel model in models) + { + writer.Write(model.ID); + writer.Write(model.NumMeshes); + writer.Write(model.StartingMesh); + writer.Write(model.MeshTree); + writer.Write(model.FrameOffset); + writer.Write(model.Animation); + + if (_version == TRGameVersion.TR5) + { + writer.Write(_tr5ModelPadding); + } + } + } +} diff --git a/TRLevelControl/Control/TR1LevelControl.cs b/TRLevelControl/Control/TR1LevelControl.cs index 4c0be93cc..cd360b4d8 100644 --- a/TRLevelControl/Control/TR1LevelControl.cs +++ b/TRLevelControl/Control/TR1LevelControl.cs @@ -105,61 +105,7 @@ protected override void Read(TRLevelReader reader) ReadMeshData(reader); - //Animations - uint numAnimations = reader.ReadUInt32(); - _level.Animations = new(); - for (int i = 0; i < numAnimations; i++) - { - _level.Animations.Add(TR2FileReadUtilities.ReadAnimation(reader)); - } - - //State Changes - uint numStateChanges = reader.ReadUInt32(); - _level.StateChanges = new(); - for (int i = 0; i < numStateChanges; i++) - { - _level.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); - } - - //Animation Dispatches - uint numAnimDispatches = reader.ReadUInt32(); - _level.AnimDispatches = new(); - for (int i = 0; i < numAnimDispatches; i++) - { - _level.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); - } - - //Animation Commands - uint numAnimCommands = reader.ReadUInt32(); - _level.AnimCommands = new(); - for (int i = 0; i < numAnimCommands; i++) - { - _level.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); - } - - //Mesh Trees - uint numMeshTrees = reader.ReadUInt32() / 4; - _level.MeshTrees = new(); - for (int i = 0; i < numMeshTrees; i++) - { - _level.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); - } - - //Frames - uint numFrames = reader.ReadUInt32(); - _level.Frames = new(); - for (int i = 0; i < numFrames; i++) - { - _level.Frames.Add(reader.ReadUInt16()); - } - - //Models - uint numModels = reader.ReadUInt32(); - _level.Models = new(); - for (int i = 0; i < numModels; i++) - { - _level.Models.Add(TR2FileReadUtilities.ReadModel(reader)); - } + ReadModelData(reader); //Static Meshes uint numStaticMeshes = reader.ReadUInt32(); @@ -264,21 +210,8 @@ protected override void Write(TRLevelWriter writer) WriteMeshData(writer); - writer.Write((uint)_level.Animations.Count); - foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } - writer.Write((uint)_level.StateChanges.Count); - foreach (TRStateChange statec in _level.StateChanges) { writer.Write(statec.Serialize()); } - writer.Write((uint)_level.AnimDispatches.Count); - foreach (TRAnimDispatch dispatch in _level.AnimDispatches) { writer.Write(dispatch.Serialize()); } - writer.Write((uint)_level.AnimCommands.Count); - foreach (TRAnimCommand cmd in _level.AnimCommands) { writer.Write(cmd.Serialize()); } - writer.Write((uint)(_level.MeshTrees.Count * 4)); //To get the correct number /= 4 is done during read, make sure to reverse it here. - foreach (TRMeshTreeNode node in _level.MeshTrees) { writer.Write(node.Serialize()); } - writer.Write((uint)_level.Frames.Count); - foreach (ushort frame in _level.Frames) { writer.Write(frame); } - - writer.Write((uint)_level.Models.Count); - foreach (TRModel model in _level.Models) { writer.Write(model.Serialize()); } + WriteModelData(writer); + writer.Write((uint)_level.StaticMeshes.Count); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } @@ -338,6 +271,30 @@ private void WriteMeshData(TRLevelWriter writer) builder.WriteObjectMeshes(writer, _level.Meshes, _level.MeshPointers); } + private void ReadModelData(TRLevelReader reader) + { + TRModelBuilder builder = new(TRGameVersion.TR1); + _level.Animations = builder.ReadAnimations(reader); + _level.StateChanges = builder.ReadStateChanges(reader); + _level.AnimDispatches = builder.ReadDispatches(reader); + _level.AnimCommands = builder.ReadCommands(reader); + _level.MeshTrees = builder.ReadTrees(reader); + _level.Frames = builder.ReadFrames(reader); + _level.Models = builder.ReadModels(reader); + } + + private void WriteModelData(TRLevelWriter writer) + { + TRModelBuilder builder = new(TRGameVersion.TR1); + builder.Write(_level.Animations, writer); + builder.Write(_level.StateChanges, writer); + builder.Write(_level.AnimDispatches, writer); + builder.Write(_level.AnimCommands, writer); + builder.Write(_level.MeshTrees, writer); + builder.Write(_level.Frames, writer); + builder.Write(_level.Models, writer); + } + private static TRRoomData ConvertToRoomData(TRRoom room) { int RoomDataOffset = 0; diff --git a/TRLevelControl/Control/TR2LevelControl.cs b/TRLevelControl/Control/TR2LevelControl.cs index 40937b721..fc41ffc43 100644 --- a/TRLevelControl/Control/TR2LevelControl.cs +++ b/TRLevelControl/Control/TR2LevelControl.cs @@ -113,61 +113,7 @@ protected override void Read(TRLevelReader reader) ReadMeshData(reader); - //Animations - uint numAnimations = reader.ReadUInt32(); - _level.Animations = new(); - for (int i = 0; i < numAnimations; i++) - { - _level.Animations.Add(TR2FileReadUtilities.ReadAnimation(reader)); - } - - //State Changes - uint numStateChanges = reader.ReadUInt32(); - _level.StateChanges = new(); - for (int i = 0; i < numStateChanges; i++) - { - _level.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); - } - - //Animation Dispatches - uint numAnimDispatches = reader.ReadUInt32(); - _level.AnimDispatches = new(); - for (int i = 0; i < numAnimDispatches; i++) - { - _level.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); - } - - //Animation Commands - uint numAnimCommands = reader.ReadUInt32(); - _level.AnimCommands = new(); - for (int i = 0; i < numAnimCommands; i++) - { - _level.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); - } - - //Mesh Trees - uint numMeshTrees = reader.ReadUInt32() / 4; - _level.MeshTrees = new(); - for (int i = 0; i < numMeshTrees; i++) - { - _level.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); - } - - //Frames - uint numFrames = reader.ReadUInt32(); - _level.Frames = new(); - for (int i = 0; i < numFrames; i++) - { - _level.Frames.Add(reader.ReadUInt16()); - } - - //Models - uint numModels = reader.ReadUInt32(); - _level.Models = new(); - for (int i = 0; i < numModels; i++) - { - _level.Models.Add(TR2FileReadUtilities.ReadModel(reader)); - } + ReadModelData(reader); uint numStaticMeshes = reader.ReadUInt32(); _level.StaticMeshes = new(); @@ -276,21 +222,8 @@ protected override void Write(TRLevelWriter writer) WriteMeshData(writer); - writer.Write((uint)_level.Animations.Count); - foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } - writer.Write((uint)_level.StateChanges.Count); - foreach (TRStateChange statec in _level.StateChanges) { writer.Write(statec.Serialize()); } - writer.Write((uint)_level.AnimDispatches.Count); - foreach (TRAnimDispatch dispatch in _level.AnimDispatches) { writer.Write(dispatch.Serialize()); } - writer.Write((uint)_level.AnimCommands.Count); - foreach (TRAnimCommand cmd in _level.AnimCommands) { writer.Write(cmd.Serialize()); } - writer.Write((uint)_level.MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. - foreach (TRMeshTreeNode node in _level.MeshTrees) { writer.Write(node.Serialize()); } - writer.Write((uint)_level.Frames.Count); - foreach (ushort frame in _level.Frames) { writer.Write(frame); } - - writer.Write((uint)_level.Models.Count); - foreach (TRModel model in _level.Models) { writer.Write(model.Serialize()); } + WriteModelData(writer); + writer.Write((uint)_level.StaticMeshes.Count); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } @@ -348,6 +281,30 @@ private void WriteMeshData(TRLevelWriter writer) builder.WriteObjectMeshes(writer, _level.Meshes, _level.MeshPointers); } + private void ReadModelData(TRLevelReader reader) + { + TRModelBuilder builder = new(TRGameVersion.TR2); + _level.Animations = builder.ReadAnimations(reader); + _level.StateChanges = builder.ReadStateChanges(reader); + _level.AnimDispatches = builder.ReadDispatches(reader); + _level.AnimCommands = builder.ReadCommands(reader); + _level.MeshTrees = builder.ReadTrees(reader); + _level.Frames = builder.ReadFrames(reader); + _level.Models = builder.ReadModels(reader); + } + + private void WriteModelData(TRLevelWriter writer) + { + TRModelBuilder builder = new(TRGameVersion.TR2); + builder.Write(_level.Animations, writer); + builder.Write(_level.StateChanges, writer); + builder.Write(_level.AnimDispatches, writer); + builder.Write(_level.AnimCommands, writer); + builder.Write(_level.MeshTrees, writer); + builder.Write(_level.Frames, writer); + builder.Write(_level.Models, writer); + } + private static TR2RoomData ConvertToRoomData(TR2Room room) { int RoomDataOffset = 0; diff --git a/TRLevelControl/Control/TR3LevelControl.cs b/TRLevelControl/Control/TR3LevelControl.cs index ab4cfa8cf..0c46fe43c 100644 --- a/TRLevelControl/Control/TR3LevelControl.cs +++ b/TRLevelControl/Control/TR3LevelControl.cs @@ -117,61 +117,7 @@ protected override void Read(TRLevelReader reader) ReadMeshData(reader); - //Animations - uint numAnimations = reader.ReadUInt32(); - _level.Animations = new(); - for (int i = 0; i < numAnimations; i++) - { - _level.Animations.Add(TR2FileReadUtilities.ReadAnimation(reader)); - } - - //State Changes - uint numStateChanges = reader.ReadUInt32(); - _level.StateChanges = new(); - for (int i = 0; i < numStateChanges; i++) - { - _level.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); - } - - //Animation Dispatches - uint numAnimDispatches = reader.ReadUInt32(); - _level.AnimDispatches = new(); - for (int i = 0; i < numAnimDispatches; i++) - { - _level.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); - } - - //Animation Commands - uint numAnimCommands = reader.ReadUInt32(); - _level.AnimCommands = new(); - for (int i = 0; i < numAnimCommands; i++) - { - _level.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); - } - - //Mesh Trees - uint numMeshTrees = reader.ReadUInt32() / 4; - _level.MeshTrees = new(); - for (int i = 0; i < numMeshTrees; i++) - { - _level.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); - } - - //Frames - uint numFrames = reader.ReadUInt32(); - _level.Frames = new(); - for (int i = 0; i < numFrames; i++) - { - _level.Frames.Add(reader.ReadUInt16()); - } - - //Models - uint numModels = reader.ReadUInt32(); - _level.Models = new(); - for (int i = 0; i < numModels; i++) - { - _level.Models.Add(TR2FileReadUtilities.ReadModel(reader)); - } + ReadModelData(reader); //Static Meshes uint numStaticMeshes = reader.ReadUInt32(); @@ -282,21 +228,8 @@ protected override void Write(TRLevelWriter writer) WriteMeshData(writer); - writer.Write((uint)_level.Animations.Count); - foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } - writer.Write((uint)_level.StateChanges.Count); - foreach (TRStateChange statec in _level.StateChanges) { writer.Write(statec.Serialize()); } - writer.Write((uint)_level.AnimDispatches.Count); - foreach (TRAnimDispatch dispatch in _level.AnimDispatches) { writer.Write(dispatch.Serialize()); } - writer.Write((uint)_level.AnimCommands.Count); - foreach (TRAnimCommand cmd in _level.AnimCommands) { writer.Write(cmd.Serialize()); } - writer.Write((uint)_level.MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. - foreach (TRMeshTreeNode node in _level.MeshTrees) { writer.Write(node.Serialize()); } - writer.Write((uint)_level.Frames.Count); - foreach (ushort frame in _level.Frames) { writer.Write(frame); } - - writer.Write((uint)_level.Models.Count); - foreach (TRModel model in _level.Models) { writer.Write(model.Serialize()); } + WriteModelData(writer); + writer.Write((uint)_level.StaticMeshes.Count); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } @@ -355,6 +288,30 @@ private void WriteMeshData(TRLevelWriter writer) builder.WriteObjectMeshes(writer, _level.Meshes, _level.MeshPointers); } + private void ReadModelData(TRLevelReader reader) + { + TRModelBuilder builder = new(TRGameVersion.TR3); + _level.Animations = builder.ReadAnimations(reader); + _level.StateChanges = builder.ReadStateChanges(reader); + _level.AnimDispatches = builder.ReadDispatches(reader); + _level.AnimCommands = builder.ReadCommands(reader); + _level.MeshTrees = builder.ReadTrees(reader); + _level.Frames = builder.ReadFrames(reader); + _level.Models = builder.ReadModels(reader); + } + + private void WriteModelData(TRLevelWriter writer) + { + TRModelBuilder builder = new(TRGameVersion.TR3); + builder.Write(_level.Animations, writer); + builder.Write(_level.StateChanges, writer); + builder.Write(_level.AnimDispatches, writer); + builder.Write(_level.AnimCommands, writer); + builder.Write(_level.MeshTrees, writer); + builder.Write(_level.Frames, writer); + builder.Write(_level.Models, writer); + } + private static TR3RoomData ConvertToRoomData(TR3Room room) { int RoomDataOffset = 0; diff --git a/TRLevelControl/Control/TR4LevelControl.cs b/TRLevelControl/Control/TR4LevelControl.cs index 782accd74..f0d685d90 100644 --- a/TRLevelControl/Control/TR4LevelControl.cs +++ b/TRLevelControl/Control/TR4LevelControl.cs @@ -190,53 +190,26 @@ private void WriteMeshData(TRLevelWriter writer) private void ReadModelData(TRLevelReader reader) { - TR4FileReadUtilities.PopulateAnimations(reader, _level); - TR4FileReadUtilities.PopulateMeshTreesFramesModels(reader, _level); + TRModelBuilder builder = new(TRGameVersion.TR4); + _level.Animations = builder.ReadAnimations(reader); + _level.StateChanges = builder.ReadStateChanges(reader); + _level.AnimDispatches = builder.ReadDispatches(reader); + _level.AnimCommands = builder.ReadCommands(reader); + _level.MeshTrees = builder.ReadTrees(reader); + _level.Frames = builder.ReadFrames(reader); + _level.Models = builder.ReadModels(reader); } private void WriteModelData(TRLevelWriter writer) { - writer.Write((uint)_level.Animations.Count); - foreach (TR4Animation anim in _level.Animations) - { - writer.Write(anim.Serialize()); - } - - writer.Write((uint)_level.StateChanges.Count); - foreach (TRStateChange sc in _level.StateChanges) - { - writer.Write(sc.Serialize()); - } - - writer.Write((uint)_level.AnimDispatches.Count); - foreach (TRAnimDispatch ad in _level.AnimDispatches) - { - writer.Write(ad.Serialize()); - } - - writer.Write((uint)_level.AnimCommands.Count); - foreach (TRAnimCommand ac in _level.AnimCommands) - { - writer.Write(ac.Serialize()); - } - - writer.Write((uint)_level.MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. - foreach (TRMeshTreeNode node in _level.MeshTrees) - { - writer.Write(node.Serialize()); - } - - writer.Write((uint)_level.Frames.Count); - foreach (ushort frame in _level.Frames) - { - writer.Write(frame); - } - - writer.Write((uint)_level.Models.Count); - foreach (TRModel model in _level.Models) - { - writer.Write(model.Serialize()); - } + TRModelBuilder builder = new(TRGameVersion.TR4); + builder.Write(_level.Animations, writer); + builder.Write(_level.StateChanges, writer); + builder.Write(_level.AnimDispatches, writer); + builder.Write(_level.AnimCommands, writer); + builder.Write(_level.MeshTrees, writer); + builder.Write(_level.Frames, writer); + builder.Write(_level.Models, writer); } private void ReadStaticMeshes(TRLevelReader reader) diff --git a/TRLevelControl/Control/TR5LevelControl.cs b/TRLevelControl/Control/TR5LevelControl.cs index 766ffafed..ea69c1022 100644 --- a/TRLevelControl/Control/TR5LevelControl.cs +++ b/TRLevelControl/Control/TR5LevelControl.cs @@ -207,53 +207,26 @@ private void WriteMeshData(TRLevelWriter writer) private void ReadModelData(TRLevelReader reader) { - TR5FileReadUtilities.PopulateAnimations(reader, _level); - TR5FileReadUtilities.PopulateMeshTreesFramesModels(reader, _level); + TRModelBuilder builder = new(TRGameVersion.TR5); + _level.Animations = builder.ReadAnimations(reader); + _level.StateChanges = builder.ReadStateChanges(reader); + _level.AnimDispatches = builder.ReadDispatches(reader); + _level.AnimCommands = builder.ReadCommands(reader); + _level.MeshTrees = builder.ReadTrees(reader); + _level.Frames = builder.ReadFrames(reader); + _level.Models = builder.ReadModels(reader); } private void WriteModelData(TRLevelWriter writer) { - writer.Write((uint)_level.Animations.Count); - foreach (TR4Animation anim in _level.Animations) - { - writer.Write(anim.Serialize()); - } - - writer.Write((uint)_level.StateChanges.Count); - foreach (TRStateChange sc in _level.StateChanges) - { - writer.Write(sc.Serialize()); - } - - writer.Write((uint)_level.AnimDispatches.Count); - foreach (TRAnimDispatch ad in _level.AnimDispatches) - { - writer.Write(ad.Serialize()); - } - - writer.Write((uint)_level.AnimCommands.Count); - foreach (TRAnimCommand ac in _level.AnimCommands) - { - writer.Write(ac.Serialize()); - } - - writer.Write((uint)_level.MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. - foreach (TRMeshTreeNode node in _level.MeshTrees) - { - writer.Write(node.Serialize()); - } - - writer.Write((uint)_level.Frames.Count); - foreach (ushort frame in _level.Frames) - { - writer.Write(frame); - } - - writer.Write((uint)_level.Models.Count); - foreach (TR5Model model in _level.Models) - { - writer.Write(model.Serialize()); - } + TRModelBuilder builder = new(TRGameVersion.TR5); + builder.Write(_level.Animations, writer); + builder.Write(_level.StateChanges, writer); + builder.Write(_level.AnimDispatches, writer); + builder.Write(_level.AnimCommands, writer); + builder.Write(_level.MeshTrees, writer); + builder.Write(_level.Frames, writer); + builder.Write(_level.Models, writer); } private void ReadStaticMeshes(TRLevelReader reader) diff --git a/TRLevelControl/IO/TRLevelReader.cs b/TRLevelControl/IO/TRLevelReader.cs index b91925aae..63875aca8 100644 --- a/TRLevelControl/IO/TRLevelReader.cs +++ b/TRLevelControl/IO/TRLevelReader.cs @@ -389,4 +389,13 @@ private void ReadFaceTexture(TRFace face, TRGameVersion version) } } } + + public FixedFloat32 ReadFixed32() + { + return new() + { + Whole = ReadInt16(), + Fraction = ReadUInt16() + }; + } } diff --git a/TRLevelControl/IO/TRLevelWriter.cs b/TRLevelControl/IO/TRLevelWriter.cs index 2825dbed1..f950fc85f 100644 --- a/TRLevelControl/IO/TRLevelWriter.cs +++ b/TRLevelControl/IO/TRLevelWriter.cs @@ -311,4 +311,10 @@ private void WriteFaceTexture(TRFace face, TRGameVersion version) } Write(texture); } + + public void Write(FixedFloat32 fixedFloat) + { + Write(fixedFloat.Whole); + Write(fixedFloat.Fraction); + } } diff --git a/TRLevelControl/Model/Base/TRAnimCommand.cs b/TRLevelControl/Model/Base/TRAnimCommand.cs index b7ab7ab9d..130fa0277 100644 --- a/TRLevelControl/Model/Base/TRAnimCommand.cs +++ b/TRLevelControl/Model/Base/TRAnimCommand.cs @@ -1,9 +1,8 @@ using System.Text; -using TRLevelControl.Serialization; namespace TRLevelControl.Model; -public class TRAnimCommand : ISerializableCompact +public class TRAnimCommand { public short Value { get; set; } @@ -15,15 +14,4 @@ public override string ToString() return sb.ToString(); } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(Value); - } - - return stream.ToArray(); - } } diff --git a/TRLevelControl/Model/Base/TRAnimDispatch.cs b/TRLevelControl/Model/Base/TRAnimDispatch.cs index 1cd675a2a..f11abb9ec 100644 --- a/TRLevelControl/Model/Base/TRAnimDispatch.cs +++ b/TRLevelControl/Model/Base/TRAnimDispatch.cs @@ -1,9 +1,8 @@ using System.Text; -using TRLevelControl.Serialization; namespace TRLevelControl.Model; -public class TRAnimDispatch : ISerializableCompact +public class TRAnimDispatch { public short Low { get; set; } @@ -24,18 +23,4 @@ public override string ToString() return sb.ToString(); } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(Low); - writer.Write(High); - writer.Write(NextAnimation); - writer.Write(NextFrame); - } - - return stream.ToArray(); - } } diff --git a/TRLevelControl/Model/Base/TRAnimation.cs b/TRLevelControl/Model/Base/TRAnimation.cs index b8b78d407..78aec0170 100644 --- a/TRLevelControl/Model/Base/TRAnimation.cs +++ b/TRLevelControl/Model/Base/TRAnimation.cs @@ -1,8 +1,6 @@ -using TRLevelControl.Serialization; +namespace TRLevelControl.Model; -namespace TRLevelControl.Model; - -public class TRAnimation : ISerializableCompact +public class TRAnimation { public uint FrameOffset { get; set; } @@ -11,12 +9,10 @@ public class TRAnimation : ISerializableCompact public byte FrameSize { get; set; } public ushort StateID { get; set; } - - //fixed Speed - 4 bytes (2 for whole 2 for frac); public FixedFloat32 Speed { get; set; } - - //fixed Accel - 4 bytes (2 for whole 2 for frac); public FixedFloat32 Accel { get; set; } + public FixedFloat32 SpeedLateral { get; set; } + public FixedFloat32 AccelLateral { get; set; } public ushort FrameStart { get; set; } @@ -33,28 +29,4 @@ public class TRAnimation : ISerializableCompact public ushort NumAnimCommands { get; set; } public ushort AnimCommand { get; set; } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(FrameOffset); - writer.Write(FrameRate); - writer.Write(FrameSize); - writer.Write(StateID); - writer.Write(Speed.Serialize()); - writer.Write(Accel.Serialize()); - writer.Write(FrameStart); - writer.Write(FrameEnd); - writer.Write(NextAnimation); - writer.Write(NextFrame); - writer.Write(NumStateChanges); - writer.Write(StateChangeOffset); - writer.Write(NumAnimCommands); - writer.Write(AnimCommand); - } - - return stream.ToArray(); - } } diff --git a/TRLevelControl/Model/Base/TRMeshTreeNode.cs b/TRLevelControl/Model/Base/TRMeshTreeNode.cs index 519ee5fdc..d14e68a36 100644 --- a/TRLevelControl/Model/Base/TRMeshTreeNode.cs +++ b/TRLevelControl/Model/Base/TRMeshTreeNode.cs @@ -1,9 +1,8 @@ using System.Text; -using TRLevelControl.Serialization; namespace TRLevelControl.Model; -public class TRMeshTreeNode : ISerializableCompact +public class TRMeshTreeNode { public uint Flags { get; set; } @@ -24,18 +23,4 @@ public override string ToString() return sb.ToString(); } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(Flags); - writer.Write(OffsetX); - writer.Write(OffsetY); - writer.Write(OffsetZ); - } - - return stream.ToArray(); - } } diff --git a/TRLevelControl/Model/Base/TRModel.cs b/TRLevelControl/Model/Base/TRModel.cs index 3fe6be1e8..4722737db 100644 --- a/TRLevelControl/Model/Base/TRModel.cs +++ b/TRLevelControl/Model/Base/TRModel.cs @@ -1,9 +1,8 @@ using System.Text; -using TRLevelControl.Serialization; namespace TRLevelControl.Model; -public class TRModel : ISerializableCompact +public class TRModel { public uint ID { get; set; } @@ -30,20 +29,4 @@ public override string ToString() return sb.ToString(); } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(ID); - writer.Write(NumMeshes); - writer.Write(StartingMesh); - writer.Write(MeshTree); - writer.Write(FrameOffset); - writer.Write(Animation); - } - - return stream.ToArray(); - } } diff --git a/TRLevelControl/Model/Base/TRStateChange.cs b/TRLevelControl/Model/Base/TRStateChange.cs index 676e4c936..385da3b0a 100644 --- a/TRLevelControl/Model/Base/TRStateChange.cs +++ b/TRLevelControl/Model/Base/TRStateChange.cs @@ -1,9 +1,8 @@ using System.Text; -using TRLevelControl.Serialization; namespace TRLevelControl.Model; -public class TRStateChange : ISerializableCompact +public class TRStateChange { public ushort StateID { get; set; } @@ -21,17 +20,4 @@ public override string ToString() return sb.ToString(); } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(StateID); - writer.Write(NumAnimDispatches); - writer.Write(AnimDispatch); - } - - return stream.ToArray(); - } } diff --git a/TRLevelControl/Model/TR4/TR4Animation.cs b/TRLevelControl/Model/TR4/TR4Animation.cs deleted file mode 100644 index 2f31b1314..000000000 --- a/TRLevelControl/Model/TR4/TR4Animation.cs +++ /dev/null @@ -1,66 +0,0 @@ -using TRLevelControl.Serialization; - -namespace TRLevelControl.Model; - -public class TR4Animation : ISerializableCompact -{ - public uint FrameOffset { get; set; } - - public byte FrameRate { get; set; } - - public byte FrameSize { get; set; } - - public ushort StateID { get; set; } - - //fixed Speed - 4 bytes (2 for whole 2 for frac); - public FixedFloat32 Speed { get; set; } - - //fixed Accel - 4 bytes (2 for whole 2 for frac); - public FixedFloat32 Accel { get; set; } - - public FixedFloat32 SpeedLateral { get; set; } - - public FixedFloat32 AccelLateral { get; set; } - - public ushort FrameStart { get; set; } - - public ushort FrameEnd { get; set; } - - public ushort NextAnimation { get; set; } - - public ushort NextFrame { get; set; } - - public ushort NumStateChanges { get; set; } - - public ushort StateChangeOffset { get; set; } - - public ushort NumAnimCommands { get; set; } - - public ushort AnimCommand { get; set; } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(FrameOffset); - writer.Write(FrameRate); - writer.Write(FrameSize); - writer.Write(StateID); - writer.Write(Speed.Serialize()); - writer.Write(Accel.Serialize()); - writer.Write(SpeedLateral.Serialize()); - writer.Write(AccelLateral.Serialize()); - writer.Write(FrameStart); - writer.Write(FrameEnd); - writer.Write(NextAnimation); - writer.Write(NextFrame); - writer.Write(NumStateChanges); - writer.Write(StateChangeOffset); - writer.Write(NumAnimCommands); - writer.Write(AnimCommand); - } - - return stream.ToArray(); - } -} diff --git a/TRLevelControl/Model/TR4/TR4Level.cs b/TRLevelControl/Model/TR4/TR4Level.cs index 0d197028a..73f81bc21 100644 --- a/TRLevelControl/Model/TR4/TR4Level.cs +++ b/TRLevelControl/Model/TR4/TR4Level.cs @@ -7,7 +7,7 @@ public class TR4Level : TRLevelBase public List FloorData { get; set; } public List Meshes { get; set; } public List MeshPointers { get; set; } - public List Animations { get; set; } + public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } public List AnimCommands { get; set; } diff --git a/TRLevelControl/Model/TR5/TR5Level.cs b/TRLevelControl/Model/TR5/TR5Level.cs index 09ea68138..349f69fd9 100644 --- a/TRLevelControl/Model/TR5/TR5Level.cs +++ b/TRLevelControl/Model/TR5/TR5Level.cs @@ -9,13 +9,13 @@ public class TR5Level : TRLevelBase public List FloorData { get; set; } public List Meshes { get; set; } public List MeshPointers { get; set; } - public List Animations { get; set; } + public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } public List AnimCommands { get; set; } public List MeshTrees { get; set; } public List Frames { get; set; } - public List Models { get; set; } + public List Models { get; set; } public List StaticMeshes { get; set; } public List SpriteTextures { get; set; } public List SpriteSequences { get; set; } diff --git a/TRLevelControl/Model/TR5/TR5Model.cs b/TRLevelControl/Model/TR5/TR5Model.cs deleted file mode 100644 index 6626fb07b..000000000 --- a/TRLevelControl/Model/TR5/TR5Model.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Text; -using TRLevelControl.Serialization; - -namespace TRLevelControl.Model; - -public class TR5Model : ISerializableCompact -{ - public uint ID { get; set; } - - public ushort NumMeshes { get; set; } - - public ushort StartingMesh { get; set; } - - public uint MeshTree { get; set; } - - public uint FrameOffset { get; set; } - - public ushort Animation { get; set; } - - public ushort Filler { get; set; } - - public override string ToString() - { - StringBuilder sb = new(base.ToString()); - - sb.Append(" ID: " + ID); - sb.Append(" NumMeshes: " + NumMeshes); - sb.Append(" StartingMesh: " + StartingMesh); - sb.Append(" MeshTree: " + MeshTree); - sb.Append(" FrameOffset: " + FrameOffset); - sb.Append(" Animation: " + Animation); - - return sb.ToString(); - } - - public byte[] Serialize() - { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) - { - writer.Write(ID); - writer.Write(NumMeshes); - writer.Write(StartingMesh); - writer.Write(MeshTree); - writer.Write(FrameOffset); - writer.Write(Animation); - writer.Write(Filler); - } - - return stream.ToArray(); - } -} diff --git a/TRLevelControl/TR2FileReadUtilities.cs b/TRLevelControl/TR2FileReadUtilities.cs index 4ed6c32b4..4192470d0 100644 --- a/TRLevelControl/TR2FileReadUtilities.cs +++ b/TRLevelControl/TR2FileReadUtilities.cs @@ -68,75 +68,6 @@ public static TR2RoomStaticMesh ReadRoomStaticMesh(BinaryReader reader) }; } - public static TRAnimation ReadAnimation(BinaryReader reader) - { - return new TRAnimation - { - FrameOffset = reader.ReadUInt32(), - FrameRate = reader.ReadByte(), - FrameSize = reader.ReadByte(), - StateID = reader.ReadUInt16(), - Speed = new FixedFloat32 - { - Whole = reader.ReadInt16(), - Fraction = reader.ReadUInt16() - }, - Accel = new FixedFloat32 - { - Whole = reader.ReadInt16(), - Fraction = reader.ReadUInt16() - }, - FrameStart = reader.ReadUInt16(), - FrameEnd = reader.ReadUInt16(), - NextAnimation = reader.ReadUInt16(), - NextFrame = reader.ReadUInt16(), - NumStateChanges = reader.ReadUInt16(), - StateChangeOffset = reader.ReadUInt16(), - NumAnimCommands = reader.ReadUInt16(), - AnimCommand = reader.ReadUInt16() - }; - } - - public static TRStateChange ReadStateChange(BinaryReader reader) - { - return new TRStateChange() - { - StateID = reader.ReadUInt16(), - NumAnimDispatches = reader.ReadUInt16(), - AnimDispatch = reader.ReadUInt16() - }; - } - - public static TRAnimDispatch ReadAnimDispatch(BinaryReader reader) - { - return new TRAnimDispatch() - { - Low = reader.ReadInt16(), - High = reader.ReadInt16(), - NextAnimation = reader.ReadInt16(), - NextFrame = reader.ReadInt16() - }; - } - - public static TRAnimCommand ReadAnimCommand(BinaryReader reader) - { - return new TRAnimCommand() - { - Value = reader.ReadInt16() - }; - } - - public static TRMeshTreeNode ReadMeshTreeNode(BinaryReader reader) - { - return new TRMeshTreeNode() - { - Flags = reader.ReadUInt32(), - OffsetX = reader.ReadInt32(), - OffsetY = reader.ReadInt32(), - OffsetZ = reader.ReadInt32() - }; - } - public static TRVertex ReadVertex(BinaryReader reader) { return new TRVertex @@ -147,19 +78,6 @@ public static TRVertex ReadVertex(BinaryReader reader) }; } - public static TRModel ReadModel(BinaryReader reader) - { - return new TRModel() - { - ID = reader.ReadUInt32(), - NumMeshes = reader.ReadUInt16(), - StartingMesh = reader.ReadUInt16(), - MeshTree = reader.ReadUInt32(), - FrameOffset = reader.ReadUInt32(), - Animation = reader.ReadUInt16() - }; - } - public static TRStaticMesh ReadStaticMesh(BinaryReader reader) { return new TRStaticMesh() diff --git a/TRLevelControl/TR4FileReadUtilities.cs b/TRLevelControl/TR4FileReadUtilities.cs index 69b475646..961649a3d 100644 --- a/TRLevelControl/TR4FileReadUtilities.cs +++ b/TRLevelControl/TR4FileReadUtilities.cs @@ -95,68 +95,6 @@ public static void PopulateFloordata(BinaryReader reader, TR4Level lvl) } } - public static void PopulateAnimations(BinaryReader reader, TR4Level lvl) - { - //Animations - uint numAnimations = reader.ReadUInt32(); - lvl.Animations = new(); - for (int i = 0; i < numAnimations; i++) - { - lvl.Animations.Add(ReadAnimation(reader)); - } - - //State Changes - uint numStateChanges = reader.ReadUInt32(); - lvl.StateChanges = new(); - for (int i = 0; i < numStateChanges; i++) - { - lvl.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); - } - - //Animation Dispatches - uint numAnimDispatches = reader.ReadUInt32(); - lvl.AnimDispatches = new(); - for (int i = 0; i < numAnimDispatches; i++) - { - lvl.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); - } - - //Animation Commands - uint numAnimCommands = reader.ReadUInt32(); - lvl.AnimCommands = new(); - for (int i = 0; i < numAnimCommands; i++) - { - lvl.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); - } - } - - public static void PopulateMeshTreesFramesModels(BinaryReader reader, TR4Level lvl) - { - //Mesh Trees - uint numMeshTrees = reader.ReadUInt32() / 4; - lvl.MeshTrees = new(); - for (int i = 0; i < numMeshTrees; i++) - { - lvl.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); - } - - //Frames - uint numFrames = reader.ReadUInt32(); - lvl.Frames = new(); - for (int i = 0; i < numFrames; i++) - { - lvl.Frames.Add(reader.ReadUInt16()); - } - - //Models - uint numModels = reader.ReadUInt32(); - lvl.Models = new(); - for (int i = 0; i < numModels; i++) - { - lvl.Models.Add(TR2FileReadUtilities.ReadModel(reader)); - } - } - public static void PopulateStaticMeshes(BinaryReader reader, TR4Level lvl) { uint numStaticMeshes = reader.ReadUInt32(); @@ -427,45 +365,6 @@ private static TR4RoomLight ReadRoomLight(BinaryReader reader) }; } - public static TR4Animation ReadAnimation(BinaryReader reader) - { - return new TR4Animation - { - FrameOffset = reader.ReadUInt32(), - FrameRate = reader.ReadByte(), - FrameSize = reader.ReadByte(), - StateID = reader.ReadUInt16(), - Speed = new FixedFloat32 - { - Whole = reader.ReadInt16(), - Fraction = reader.ReadUInt16() - }, - Accel = new FixedFloat32 - { - Whole = reader.ReadInt16(), - Fraction = reader.ReadUInt16() - }, - SpeedLateral = new FixedFloat32 - { - Whole = reader.ReadInt16(), - Fraction = reader.ReadUInt16() - }, - AccelLateral = new FixedFloat32 - { - Whole = reader.ReadInt16(), - Fraction = reader.ReadUInt16() - }, - FrameStart = reader.ReadUInt16(), - FrameEnd = reader.ReadUInt16(), - NextAnimation = reader.ReadUInt16(), - NextFrame = reader.ReadUInt16(), - NumStateChanges = reader.ReadUInt16(), - StateChangeOffset = reader.ReadUInt16(), - NumAnimCommands = reader.ReadUInt16(), - AnimCommand = reader.ReadUInt16() - }; - } - public static TR4FlyByCamera ReadFlybyCamera(BinaryReader reader) { return new TR4FlyByCamera diff --git a/TRLevelControl/TR5FileReadUtilities.cs b/TRLevelControl/TR5FileReadUtilities.cs index b1cade44f..d7c605c26 100644 --- a/TRLevelControl/TR5FileReadUtilities.cs +++ b/TRLevelControl/TR5FileReadUtilities.cs @@ -212,82 +212,6 @@ public static void PopulateFloordata(BinaryReader reader, TR5Level lvl) } } - public static void PopulateAnimations(BinaryReader reader, TR5Level lvl) - { - //Animations - uint numAnimations = reader.ReadUInt32(); - lvl.Animations = new(); - for (int i = 0; i < numAnimations; i++) - { - lvl.Animations.Add(TR4FileReadUtilities.ReadAnimation(reader)); - } - - //State Changes - uint numStateChanges = reader.ReadUInt32(); - lvl.StateChanges = new(); - for (int i = 0; i < numStateChanges; i++) - { - lvl.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); - } - - //Animation Dispatches - uint numAnimDispatches = reader.ReadUInt32(); - lvl.AnimDispatches = new(); - for (int i = 0; i < numAnimDispatches; i++) - { - lvl.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); - } - - //Animation Commands - uint numAnimCommands = reader.ReadUInt32(); - lvl.AnimCommands = new(); - for (int i = 0; i < numAnimCommands; i++) - { - lvl.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); - } - } - - public static void PopulateMeshTreesFramesModels(BinaryReader reader, TR5Level lvl) - { - //Mesh Trees - uint numMeshTrees = reader.ReadUInt32() / 4; - lvl.MeshTrees = new(); - for (int i = 0; i < numMeshTrees; i++) - { - lvl.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); - } - - //Frames - uint numFrames = reader.ReadUInt32(); - lvl.Frames = new(); - for (int i = 0; i < numFrames; i++) - { - lvl.Frames.Add(reader.ReadUInt16()); - } - - //Models - uint numModels = reader.ReadUInt32(); - lvl.Models = new(); - for (int i = 0; i < numModels; i++) - { - lvl.Models.Add(ReadTR5Model(reader)); - } - } - - private static TR5Model ReadTR5Model(BinaryReader reader) - { - return new TR5Model() - { - ID = reader.ReadUInt32(), - NumMeshes = reader.ReadUInt16(), - StartingMesh = reader.ReadUInt16(), - MeshTree = reader.ReadUInt32(), - FrameOffset = reader.ReadUInt32(), - Animation = reader.ReadUInt16(), - Filler = reader.ReadUInt16() - }; - } - public static void PopulateStaticMeshes(BinaryReader reader, TR5Level lvl) { uint numStaticMeshes = reader.ReadUInt32();