From de655515fa5f3f25626da2299af6511217097cb8 Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Thu, 24 Mar 2022 21:15:16 +0000 Subject: [PATCH] #314 Enemy Meshes Ensures that any clones of Lara remain visible if Lara herself is invisible. This is done by duplicating the meshes before we clear them. --- TRRandomizerCore/Helpers/MeshEditor.cs | 61 +++++++++++++++++++ .../Randomizers/TR2/TR2OutfitRandomizer.cs | 33 ++++++++-- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/TRRandomizerCore/Helpers/MeshEditor.cs b/TRRandomizerCore/Helpers/MeshEditor.cs index fe2809d70..a0455605f 100644 --- a/TRRandomizerCore/Helpers/MeshEditor.cs +++ b/TRRandomizerCore/Helpers/MeshEditor.cs @@ -116,6 +116,67 @@ public void RemoveColouredTriangles(IEnumerable indices) Mesh.NumColouredTriangles = (short)triangles.Count; } + public TRMesh CloneMesh(TRMesh mesh) + { + TRMesh clone = new TRMesh + { + Centre = mesh.Centre, + CollRadius = mesh.CollRadius, + ColouredRectangles = new TRFace4[mesh.NumColouredRectangles], + ColouredTriangles = new TRFace3[mesh.NumColouredTriangles], + Lights = mesh.Lights, + Normals = mesh.Normals, + NumColouredRectangles = mesh.NumColouredRectangles, + NumColouredTriangles = mesh.NumColouredTriangles, + NumNormals = mesh.NumNormals, + NumTexturedRectangles = mesh.NumTexturedRectangles, + NumTexturedTriangles = mesh.NumTexturedTriangles, + NumVertices = mesh.NumVertices, + Pointer = mesh.Pointer, + TexturedRectangles = new TRFace4[mesh.NumTexturedRectangles], + TexturedTriangles = new TRFace3[mesh.NumTexturedTriangles], + Vertices = mesh.Vertices + }; + + for (int i = 0; i < mesh.NumColouredRectangles; i++) + { + clone.ColouredRectangles[i] = new TRFace4 + { + Texture = mesh.ColouredRectangles[i].Texture, + Vertices = mesh.ColouredRectangles[i].Vertices + }; + } + + for (int i = 0; i < mesh.NumColouredTriangles; i++) + { + clone.ColouredTriangles[i] = new TRFace3 + { + Texture = mesh.ColouredTriangles[i].Texture, + Vertices = mesh.ColouredTriangles[i].Vertices + }; + } + + for (int i = 0; i < mesh.NumTexturedRectangles; i++) + { + clone.TexturedRectangles[i] = new TRFace4 + { + Texture = mesh.TexturedRectangles[i].Texture, + Vertices = mesh.TexturedRectangles[i].Vertices + }; + } + + for (int i = 0; i < mesh.NumTexturedTriangles; i++) + { + clone.TexturedTriangles[i] = new TRFace3 + { + Texture = mesh.TexturedTriangles[i].Texture, + Vertices = mesh.TexturedTriangles[i].Vertices + }; + } + + return clone; + } + public void WriteToLevel(TR2Level level) { TRMeshUtilities.UpdateMeshPointers(level, Mesh, _oldLength); diff --git a/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs index 8943c56aa..070804393 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs @@ -237,8 +237,14 @@ protected override void ProcessImpl() private bool Import(TR2CombinedLevel level, TR2Entities lara) { + List models = level.Data.Models.ToList(); + TRModel laraModel = models.Find(m => m.ID == (uint)TR2Entities.Lara); + List laraClones = models.FindAll(m => m.MeshTree == laraModel.MeshTree && m != laraModel); + if (lara == TR2Entities.LaraInvisible) { + // #314 Ensure cloned Laras remain visible + CloneLaraMeshes(level, laraClones, laraModel); // No import needed, just clear each of Lara's meshes. A haircut is implied // with this and we don't need to alter the outfit. HideEntities(level, _invisibleLaraEntities); @@ -272,10 +278,6 @@ private bool Import(TR2CombinedLevel level, TR2Entities lara) try { - List models = level.Data.Models.ToList(); - TRModel laraModel = models.Find(m => m.ID == (uint)TR2Entities.Lara); - List laraClones = models.FindAll(m => m.MeshTree == laraModel.MeshTree); - // Try to import the selected models into the level. importer.Import(); @@ -313,6 +315,29 @@ private bool Import(TR2CombinedLevel level, TR2Entities lara) } } + private void CloneLaraMeshes(TR2CombinedLevel level, List clones, TRModel laraModel) + { + if (clones.Count > 0) + { + MeshEditor editor = new MeshEditor(); + TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, laraModel); + int firstMeshIndex = -1; + for (int i = 0; i < meshes.Length; i++) + { + int insertedIndex = TRMeshUtilities.InsertMesh(level.Data, editor.CloneMesh(meshes[i])); + if (firstMeshIndex == -1) + { + firstMeshIndex = insertedIndex; + } + } + + foreach (TRModel model in clones) + { + model.StartingMesh = (ushort)firstMeshIndex; + } + } + } + private void HideEntities(TR2CombinedLevel level, IEnumerable entities) { MeshEditor editor = new MeshEditor();