diff --git a/CUE4Parse b/CUE4Parse index 78389978..455b72e5 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 783899787bf421b3a3cc47b030348f89246fb07a +Subproject commit 455b72e5e38bfe9476b5823bc642fc8ef488347f diff --git a/FModel/Creator/Bases/FN/BasePlaylist.cs b/FModel/Creator/Bases/FN/BasePlaylist.cs index fe7fd7c9..9110158c 100644 --- a/FModel/Creator/Bases/FN/BasePlaylist.cs +++ b/FModel/Creator/Bases/FN/BasePlaylist.cs @@ -34,7 +34,7 @@ public override void ParseForInfo() return; var playlist = _apiEndpointView.FortniteApi.GetPlaylist(playlistName.Text); - if (!playlist.IsSuccess || !playlist.Data.Images.HasShowcase || + if (!playlist.IsSuccess || playlist.Data.Images is not { HasShowcase: true } || !_apiEndpointView.FortniteApi.TryGetBytes(playlist.Data.Images.Showcase, out var image)) return; @@ -74,4 +74,4 @@ private void DrawMissionIcon(SKCanvas c) if (_missionIcon == null) return; c.DrawBitmap(_missionIcon, new SKPoint(5, 5), ImagePaint); } -} \ No newline at end of file +} diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index f93745e3..dbae3fed 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -5,9 +5,9 @@ net8.0-windows true FModel.ico - 4.4.3.6 - 4.4.3.6 - 4.4.3.6 + 4.4.4.0 + 4.4.4.0 + 4.4.4.0 false true win-x64 diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 2b985f24..55eb71f1 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -851,6 +851,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat "JunoBuildingPropAccountItemDefinition" => true, _ => false }: + case UPaperSprite when isNone && UserSettings.Default.PreviewMaterials: case UStaticMesh when isNone && UserSettings.Default.PreviewStaticMeshes: case USkeletalMesh when isNone && UserSettings.Default.PreviewSkeletalMeshes: case USkeleton when isNone && UserSettings.Default.SaveSkeletonAsMesh: diff --git a/FModel/ViewModels/TabControlViewModel.cs b/FModel/ViewModels/TabControlViewModel.cs index 0a86f055..1afe5c77 100644 --- a/FModel/ViewModels/TabControlViewModel.cs +++ b/FModel/ViewModels/TabControlViewModel.cs @@ -68,9 +68,13 @@ private void SetImage(SKBitmap bitmap) Image = null; return; } + _bmp = bitmap; using var data = _bmp.Encode(NoAlpha ? ETextureFormat.Jpeg : UserSettings.Default.TextureExportFormat, 100); using var stream = new MemoryStream(ImageBuffer = data.ToArray(), false); + if (UserSettings.Default.TextureExportFormat == ETextureFormat.Tga) + return; + var image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; @@ -305,6 +309,7 @@ private void SaveImage(TabImage image, bool updateUi) var ext = UserSettings.Default.TextureExportFormat switch { ETextureFormat.Png => ".png", + ETextureFormat.Jpeg => ".jpg", ETextureFormat.Tga => ".tga", _ => ".png" }; diff --git a/FModel/Views/Snooper/Models/StaticModel.cs b/FModel/Views/Snooper/Models/StaticModel.cs index 369295e2..0d669a83 100644 --- a/FModel/Views/Snooper/Models/StaticModel.cs +++ b/FModel/Views/Snooper/Models/StaticModel.cs @@ -1,7 +1,10 @@ -using System.Numerics; +using System; +using System.Numerics; using CUE4Parse_Conversion.Meshes.PSK; using CUE4Parse.UE4.Assets.Exports.Material; using CUE4Parse.UE4.Assets.Exports.StaticMesh; +using CUE4Parse.UE4.Assets.Exports.Texture; +using CUE4Parse.UE4.Objects.Core.Math; using CUE4Parse.UE4.Objects.PhysicsEngine; using FModel.Views.Snooper.Shading; using OpenTK.Graphics.OpenGL4; @@ -52,6 +55,59 @@ public StaticModel(UMaterialInterface unrealMaterial, CStaticMesh staticMesh) : Box = staticMesh.BoundingBox * 1.5f * Constants.SCALE_DOWN_RATIO; } + public StaticModel(UPaperSprite paperSprite, UTexture2D texture) : base(paperSprite) + { + Indices = new uint[paperSprite.BakedRenderData.Length]; + for (int i = 0; i < Indices.Length; i++) + { + Indices[i] = (uint) i; + } + + Vertices = new float[paperSprite.BakedRenderData.Length * VertexSize]; + for (int i = 0; i < paperSprite.BakedRenderData.Length; i++) + { + var count = 0; + var baseIndex = i * VertexSize; + var vert = paperSprite.BakedRenderData[i]; + var u = vert.Z; + var v = vert.W; + + Vertices[baseIndex + count++] = i; + Vertices[baseIndex + count++] = vert.X * paperSprite.PixelsPerUnrealUnit * Constants.SCALE_DOWN_RATIO; + Vertices[baseIndex + count++] = vert.Y * paperSprite.PixelsPerUnrealUnit * Constants.SCALE_DOWN_RATIO; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = 0; + Vertices[baseIndex + count++] = u; + Vertices[baseIndex + count++] = v; + Vertices[baseIndex + count++] = .5f; + } + + Materials = new Material[1]; + if (paperSprite.DefaultMaterial?.TryLoad(out UMaterialInstance unrealMaterial) ?? false) + { + Materials[0] = new Material(unrealMaterial); + } + else + { + Materials[0] = new Material(); + } + Materials[0].Parameters.Textures[CMaterialParams2.FallbackDiffuse] = texture; + Materials[0].IsUsed = true; + + Sections = new Section[1]; + Sections[0] = new Section(0, Indices.Length, 0); + + AddInstance(Transform.Identity); + + var backward = new FVector(0, Math.Max(paperSprite.BakedSourceDimension.X, paperSprite.BakedSourceDimension.Y) / 2, 0); + Box = new FBox(-backward, backward) * Constants.SCALE_DOWN_RATIO; + } + public StaticModel(UStaticMesh export, CStaticMesh staticMesh, Transform transform = null) : base(export, staticMesh.LODs[LodLevel], export.Materials, staticMesh.LODs[LodLevel].Verts, staticMesh.LODs.Count, transform) { diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index 4bc0d4d9..f00961a5 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -103,6 +103,9 @@ public void Load(CancellationToken cancellationToken, UObject export) LoadJunoWorld(cancellationToken, bp, Transform.Identity); Color = VertexColor.Colors; break; + case UPaperSprite ps: + LoadPaperSprite(ps); + break; } CameraOp.Mode = _saveCameraMode ? UserSettings.Default.CameraMode : Camera.WorldMode.FlyCam; SetupCamera(); @@ -397,6 +400,23 @@ private void LoadMaterialInstance(UMaterialInstance original) Options.SelectModel(guid); } + private void LoadPaperSprite(UPaperSprite original) + { + if (!(original.BakedSourceTexture?.TryLoad(out UTexture2D texture) ?? false)) + return; + + var guid = texture.LightingGuid; + if (Options.TryGetModel(guid, out var model)) + { + model.AddInstance(Transform.Identity); + Application.Current.Dispatcher.Invoke(() => model.SetupInstances()); + return; + } + + Options.Models[guid] = new StaticModel(original, texture); + Options.SelectModel(guid); + } + private void SetupCamera() { if (Options.TryGetModel(out var model)) diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index c5d44801..4b182f79 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -1014,8 +1014,8 @@ private void Theme() style.Colors[(int) ImGuiCol.Tab] = new Vector4(0.15f, 0.15f, 0.19f, 1.00f); style.Colors[(int) ImGuiCol.TabHovered] = new Vector4(0.35f, 0.35f, 0.41f, 0.80f); style.Colors[(int) ImGuiCol.TabSelected] = new Vector4(0.23f, 0.24f, 0.29f, 1.00f); - style.Colors[(int) ImGuiCol.TabSelectedOverline] = new Vector4(0.15f, 0.15f, 0.15f, 1.00f); - style.Colors[(int) ImGuiCol.TabDimmed] = new Vector4(0.23f, 0.24f, 0.29f, 1.00f); + style.Colors[(int) ImGuiCol.TabDimmed] = new Vector4(0.15f, 0.15f, 0.15f, 1.00f); + style.Colors[(int) ImGuiCol.TabDimmedSelected] = new Vector4(0.23f, 0.24f, 0.29f, 1.00f); style.Colors[(int) ImGuiCol.DockingPreview] = new Vector4(0.26f, 0.59f, 0.98f, 0.70f); style.Colors[(int) ImGuiCol.DockingEmptyBg] = new Vector4(0.20f, 0.20f, 0.20f, 1.00f); style.Colors[(int) ImGuiCol.PlotLines] = new Vector4(0.61f, 0.61f, 0.61f, 1.00f);