diff --git a/CUE4Parse b/CUE4Parse index a2be829b..0e178d32 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit a2be829ba154755ad195be94a84ddc6d99ab887e +Subproject commit 0e178d32bef3b571cabca5f041dae102d209f2d3 diff --git a/FModel/Constants.cs b/FModel/Constants.cs index e2667514..2f53fc8a 100644 --- a/FModel/Constants.cs +++ b/FModel/Constants.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System.Numerics; +using System.Reflection; using CUE4Parse.UE4.Objects.Core.Misc; namespace FModel; @@ -27,4 +28,19 @@ public static class Constants public const string _VAL_LIVE_TRIGGER = "valorant-live.manifest"; public const string _NO_PRESET_TRIGGER = "Hand Made"; + + public static int PALETTE_LENGTH => COLOR_PALETTE.Length; + public static readonly Vector3[] COLOR_PALETTE = + { + new (0.231f, 0.231f, 0.231f), // Dark gray + new (0.376f, 0.490f, 0.545f), // Teal + new (0.957f, 0.263f, 0.212f), // Red + new (0.196f, 0.804f, 0.196f), // Green + new (0.957f, 0.647f, 0.212f), // Orange + new (0.612f, 0.153f, 0.690f), // Purple + new (0.129f, 0.588f, 0.953f), // Blue + new (1.000f, 0.920f, 0.424f), // Yellow + new (0.824f, 0.412f, 0.118f), // Brown + new (0.612f, 0.800f, 0.922f) // Light blue + }; } diff --git a/FModel/Resources/default.frag b/FModel/Resources/default.frag index 438d1147..7e6aac04 100644 --- a/FModel/Resources/default.frag +++ b/FModel/Resources/default.frag @@ -90,6 +90,7 @@ uniform Light uLights[MAX_LIGHT_COUNT]; uniform int uNumLights; uniform int uUvCount; uniform bool uHasVertexColors; +uniform vec3 uSectionColor; uniform bool bVertexColors[6]; uniform vec3 uViewPos; @@ -211,7 +212,11 @@ vec3 CalcSpotLight(int layer, vec3 normals, Light light) void main() { - if (bVertexColors[2] && uHasVertexColors) + if (bVertexColors[1]) + { + FragColor = vec4(uSectionColor, 1.0); + } + else if (bVertexColors[2] && uHasVertexColors) { FragColor = fColor; } @@ -219,11 +224,11 @@ void main() { int layer = LayerToIndex(); vec3 normals = ComputeNormals(layer); - FragColor = vec4(normals, 1); + FragColor = vec4(normals, 1.0); } else if (bVertexColors[4]) { - FragColor = vec4(fTexCoords, 0, 1); + FragColor = vec4(fTexCoords, 0.0, 1.0); } else { @@ -257,7 +262,6 @@ void main() result += uParameters.Emissive[layer].Color.rgb * emissive.rgb * uParameters.EmissiveMult; } - if (!bVertexColors[1]) { result += CalcLight(layer, normals, uViewPos, vec3(0.75), 1.0, false); diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 9f5b0c8a..764367f2 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -829,6 +829,8 @@ public class CUE4ParseViewModel : ViewModel case USkeleton when UserSettings.Default.SaveSkeletonAsMesh && HasFlag(bulk, EBulkType.Meshes): // case UMaterialInstance when HasFlag(bulk, EBulkType.Materials): // read the fucking json case UAnimSequence when HasFlag(bulk, EBulkType.Animations): + case UAnimMontage when HasFlag(bulk, EBulkType.Animations): + case UAnimComposite when HasFlag(bulk, EBulkType.Animations): { SaveExport(export, HasFlag(bulk, EBulkType.Auto)); return true; diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index d1785e68..81312284 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -84,8 +84,8 @@ public class Model : IDisposable public bool HasSockets => Sockets.Count > 0; public readonly List Sockets; - public bool HasMorphTargets => Morphs.Length > 0; - public readonly Morph[] Morphs; + public bool HasMorphTargets => Morphs.Count > 0; + public readonly List Morphs; private string _attachedTo = string.Empty; private readonly List _attachedFor = new (); @@ -114,7 +114,7 @@ public class Model : IDisposable UvCount = 1; Box = new FBox(new FVector(-2f), new FVector(2f)); Sockets = new List(); - Morphs = Array.Empty(); + Morphs = new List(); Transforms = new List(); } @@ -150,10 +150,13 @@ public class Model : IDisposable Sockets.Add(new Socket(socket)); } - Morphs = new Morph[export.MorphTargets.Length]; - for (var i = 0; i < Morphs.Length; i++) + for (var i = 0; i < export.MorphTargets.Length; i++) { - Morphs[i] = new Morph(Vertices, VertexSize, export.MorphTargets[i].Load()); + if (!export.MorphTargets[i].TryLoad(out UMorphTarget morphTarget) || + morphTarget.MorphLODModels.Length < 1 || morphTarget.MorphLODModels[0].Vertices.Length < 1) + continue; + + Morphs.Add(new Morph(Vertices, VertexSize, morphTarget)); } } @@ -355,7 +358,7 @@ public class Model : IDisposable if (HasSkeleton) Skeleton.Setup(); if (HasMorphTargets) { - for (uint morph = 0; morph < Morphs.Length; morph++) + for (int morph = 0; morph < Morphs.Count; morph++) { Morphs[morph].Setup(); if (morph == 0) @@ -398,7 +401,12 @@ public class Model : IDisposable foreach (var section in Sections) { if (!section.Show) continue; - if (!outline) Materials[section.MaterialIndex].Render(shader); + if (!outline) + { + shader.SetUniform("uSectionColor", section.Color); + Materials[section.MaterialIndex].Render(shader); + } + GL.DrawElementsInstanced(PrimitiveType.Triangles, section.FacesCount, DrawElementsType.UnsignedInt, section.FirstFaceIndexPtr, TransformsCount); } _vao.Unbind(); @@ -443,10 +451,11 @@ public class Model : IDisposable } Sockets.Clear(); if (HasMorphTargets) _morphVbo.Dispose(); - for (var morph = 0; morph < Morphs.Length; morph++) + for (var morph = 0; morph < Morphs.Count; morph++) { Morphs[morph]?.Dispose(); } + Morphs.Clear(); GL.DeleteProgram(_handle); } diff --git a/FModel/Views/Snooper/Models/Section.cs b/FModel/Views/Snooper/Models/Section.cs index e39d24b4..0c96ed90 100644 --- a/FModel/Views/Snooper/Models/Section.cs +++ b/FModel/Views/Snooper/Models/Section.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using FModel.Views.Snooper.Shading; namespace FModel.Views.Snooper.Models; @@ -9,6 +10,7 @@ public class Section public readonly int FacesCount; public readonly int FirstFaceIndex; public readonly IntPtr FirstFaceIndexPtr; + public readonly Vector3 Color; public bool Show; @@ -18,6 +20,7 @@ public class Section FacesCount = facesCount; FirstFaceIndex = firstFaceIndex; FirstFaceIndexPtr = new IntPtr(FirstFaceIndex * sizeof(uint)); + Color = Constants.COLOR_PALETTE[index % Constants.PALETTE_LENGTH]; Show = true; } diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index 34541888..4a401e7f 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -27,6 +27,15 @@ using FModel.Views.Snooper.Shading; namespace FModel.Views.Snooper; +public enum VertexColor +{ + Default, + Sections, + Colors, + Normals, + TextureCoordinates +} + public class Renderer : IDisposable { private readonly Skybox _skybox; @@ -40,7 +49,7 @@ public class Renderer : IDisposable public bool ShowGrid; public bool ShowLights; public bool AnimateWithRotationOnly; - public int VertexColor; + public VertexColor Color; public Camera CameraOp { get; } public PickingTexture Picking { get; } @@ -58,7 +67,7 @@ public class Renderer : IDisposable ShowSkybox = UserSettings.Default.ShowSkybox; ShowGrid = UserSettings.Default.ShowGrid; AnimateWithRotationOnly = UserSettings.Default.AnimateWithRotationOnly; - VertexColor = 0; // default + Color = VertexColor.Default; } public void Load(CancellationToken cancellationToken, UObject export) @@ -89,7 +98,6 @@ public class Renderer : IDisposable model.Materials[section.MaterialIndex].SwapMaterial(unrealMaterial); Application.Current.Dispatcher.Invoke(() => model.Materials[section.MaterialIndex].Setup(Options, model.UvCount)); - Options.SwapMaterial(false); } public void Animate(UObject anim) => Animate(anim, Options.SelectedModel); @@ -192,7 +200,6 @@ public class Renderer : IDisposable Options.Tracker.IsPaused = false; Options.Tracker.SafeSetMaxElapsedTime(maxElapsedTime); - Options.AnimateMesh(false); } public void Setup() @@ -218,7 +225,7 @@ public class Renderer : IDisposable _shader.Render(viewMatrix, CameraOp.Position, projMatrix); for (int i = 0; i < 5; i++) - _shader.SetUniform($"bVertexColors[{i}]", i == VertexColor); + _shader.SetUniform($"bVertexColors[{i}]", i == (int) Color); // update animations if (Options.Animations.Count > 0) Options.Tracker.Update(deltaSeconds); diff --git a/FModel/Views/Snooper/Shading/TextureHelper.cs b/FModel/Views/Snooper/Shading/TextureHelper.cs index 061ef7f5..b721414c 100644 --- a/FModel/Views/Snooper/Shading/TextureHelper.cs +++ b/FModel/Views/Snooper/Shading/TextureHelper.cs @@ -19,6 +19,7 @@ public static class TextureHelper case "HK_PROJECT": case "COSMICSHAKE": case "PHOENIX": + case "ATOMICHEART": { texture.SwizzleMask = new [] { diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index 09d09e60..710810c8 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -217,8 +217,10 @@ public class SnimGui ImGui.PopID();Layout("Animate With Rotation Only");ImGui.PushID(4); ImGui.Checkbox("", ref s.Renderer.AnimateWithRotationOnly); ImGui.PopID();Layout("Vertex Colors");ImGui.PushID(5); - ImGui.Combo("vertex_colors", ref s.Renderer.VertexColor, - "Default\0Diffuse Only\0Colors\0Normals\0Texture Coordinates\0"); + var c = (int) s.Renderer.Color; + ImGui.Combo("vertex_colors", ref c, + "Default\0Sections\0Colors\0Normals\0Texture Coordinates\0"); + s.Renderer.Color = (VertexColor) c; ImGui.PopID(); ImGui.EndTable(); @@ -549,6 +551,10 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio { ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, ImGui.GetColorU32(new Vector4(1, 0, 0, .5f))); } + else if (s.Renderer.Color == VertexColor.Sections) + { + ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, ImGui.GetColorU32(new Vector4(section.Color, 0.5f))); + } ImGui.Text(section.MaterialIndex.ToString("D")); ImGui.TableNextColumn(); @@ -607,7 +613,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio if (ImGui.BeginListBox("", box)) { - for (int i = 0; i < model.Morphs.Length; i++) + for (int i = 0; i < model.Morphs.Count; i++) { ImGui.PushID(i); if (ImGui.Selectable(model.Morphs[i].Name, s.Renderer.Options.SelectedMorph == i)) diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs index 322e644f..fbfb2a9c 100644 --- a/FModel/Views/Snooper/Snooper.cs +++ b/FModel/Views/Snooper/Snooper.cs @@ -60,6 +60,8 @@ public class Snooper : GameWindow public override void Run() { + Renderer.Options.SwapMaterial(false); + Renderer.Options.AnimateMesh(false); Application.Current.Dispatcher.Invoke(delegate { WindowShouldClose(false, false);