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);