diff --git a/CUE4Parse b/CUE4Parse
index c33075ab..5a52cb3d 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit c33075abbeb030c0a7d6fc12ea0913c982232e64
+Subproject commit 5a52cb3d467fe81d219e675f22b1c81e49bf6f56
diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index ee406e32..cc4a01eb 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -6,8 +6,8 @@
true
FModel.ico
4.3.2
- 4.3.2.0
- 4.3.2.0
+ 4.3.2.1
+ 4.3.2.1
false
true
win-x64
diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs
index b07c5ae1..ad0c52d1 100644
--- a/FModel/MainWindow.xaml.cs
+++ b/FModel/MainWindow.xaml.cs
@@ -79,7 +79,7 @@ public partial class MainWindow
#if DEBUG
await _threadWorkerView.Begin(cancellationToken =>
_applicationView.CUE4Parse.Extract(cancellationToken,
- "FortniteGame/Content/Athena/Artemis/Maps/Buildings/15x25/Artemis_Blimp_party.umap"));
+ "FortniteGame/Content/Athena/Artemis/Maps/Buildings/5x5/Artemis_5x5_Shop_AB.umap"));
#endif
}
diff --git a/FModel/Views/Snooper/Material.cs b/FModel/Views/Snooper/Material.cs
index cccfa589..4582e60a 100644
--- a/FModel/Views/Snooper/Material.cs
+++ b/FModel/Views/Snooper/Material.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using CUE4Parse.UE4.Assets.Exports.Material;
using CUE4Parse.UE4.Assets.Exports.Texture;
using OpenTK.Graphics.OpenGL4;
@@ -117,11 +118,21 @@ public class Material : IDisposable
array[i] = array[i - 1];
}
}
+ else if (Parameters.Colors.TryGetValue("Color", out var linearColor)) // POC
+ {
+ for (int i = 0; i < array.Length; i++)
+ array[i] = new Texture(linearColor);
+ }
else if (Parameters.Textures.TryGetValue(fallback, out var u) && u is UTexture2D o && cache.TryGetCachedTexture(o, out var t))
{
for (int i = 0; i < array.Length; i++)
array[i] = t;
}
+ else if (Parameters.Textures.First() is { Value: UTexture2D d } && cache.TryGetCachedTexture(d, out var rip))
+ {
+ for (int i = 0; i < array.Length; i++)
+ array[i] = rip;
+ }
}
public void Render(Shader shader)
diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs
index 643b31e1..916cc6d9 100644
--- a/FModel/Views/Snooper/Renderer.cs
+++ b/FModel/Views/Snooper/Renderer.cs
@@ -94,7 +94,7 @@ public class Renderer : IDisposable
private Camera SetupCamera(FBox box)
{
- var far = Math.Abs(box.Max.Max());
+ var far = box.Max.AbsMax();
var center = box.GetCenter();
return new Camera(
new Vector3(0f, center.Z, box.Max.Y * 3),
@@ -151,8 +151,22 @@ public class Renderer : IDisposable
{
cancellationToken.ThrowIfCancellationRequested();
- if (persistentLevel.Actors[i].Load() is not { } actor ||actor.ExportType == "LODActor" ||
- !actor.TryGetValue(out FPackageIndex staticMeshComponent, "StaticMeshComponent", "Mesh") ||
+ if (persistentLevel.Actors[i].Load() is not { } actor || actor.ExportType == "LODActor") continue;
+
+ if (actor.ExportType == "LevelBounds" && actor.TryGetValue(out FPackageIndex boxComponent, "BoxComponent") &&
+ boxComponent.Load() is { } boxObject && boxObject.TryGetValue(out FVector relativeLocation, "RelativeLocation") &&
+ boxObject.TryGetValue(out FVector relativeScale3D, "RelativeScale3D"))
+ {
+ var direction = relativeLocation.ToMapVector() * Constants.SCALE_DOWN_RATIO;
+ var position = relativeScale3D.ToMapVector() / 2f * Constants.SCALE_DOWN_RATIO;
+ var far = position.AbsMax();
+ ret = new Camera(
+ new Vector3(position.X, position.Y, position.Z),
+ new Vector3(direction.X, direction.Y, direction.Z),
+ 0.01f, far * 25f, far / 10f);
+ }
+
+ if (!actor.TryGetValue(out FPackageIndex staticMeshComponent, "StaticMeshComponent", "Mesh") ||
staticMeshComponent.Load() is not { } staticMeshComp) continue;
if (!staticMeshComp.TryGetValue(out FPackageIndex staticMesh, "StaticMesh") && actor.Class is UBlueprintGeneratedClass)
@@ -167,11 +181,10 @@ public class Renderer : IDisposable
var guid = m.LightingGuid;
var transform = new Transform
{
- Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO,
+ Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector).ToMapVector() * Constants.SCALE_DOWN_RATIO,
Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator),
- Scale = staticMeshComp.GetOrDefault("RelativeScale3D", FVector.OneVector)
+ Scale = staticMeshComp.GetOrDefault("RelativeScale3D", FVector.OneVector).ToMapVector()
};
- transform.Rotation.Yaw = -transform.Rotation.Yaw;
if (Cache.Models.TryGetValue(guid, out var model))
{
diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs
index 1b6cab06..5cc0aeb2 100644
--- a/FModel/Views/Snooper/SnimGui.cs
+++ b/FModel/Views/Snooper/SnimGui.cs
@@ -37,8 +37,7 @@ public class SnimGui
ImGui.Begin("Camera");
ImGui.DragFloat("Speed", ref s.Camera.Speed, 0.01f);
- ImGui.DragFloat("Near", ref s.Camera.Near, 0.1f, 0.01f, s.Camera.Far - 0.1f, "%.2f m", ImGuiSliderFlags.AlwaysClamp);
- ImGui.DragFloat("Far", ref s.Camera.Far, 0.1f, s.Camera.Near + 0.1f, 0f, "%.2f m", ImGuiSliderFlags.AlwaysClamp);
+ ImGui.DragFloat("Far Plane", ref s.Camera.Far, 0.1f, 5f, s.Camera.Far * 2f, "%.2f m", ImGuiSliderFlags.AlwaysClamp);
ImGui.End();
ImGui.Begin("World");
ImGui.End();
@@ -175,7 +174,7 @@ public class SnimGui
if (ImGui.Button("Go To"))
{
var instancePos = model.Transforms[model.SelectedInstance].Position;
- s.Camera.Position = new Vector3(instancePos.X, instancePos.Z, instancePos.Y);
+ s.Camera.Position = new Vector3(instancePos.X, instancePos.Y, instancePos.Z);
}
ImGui.NextColumn(); ImGui.Checkbox("Show", ref model.Show);
ImGui.NextColumn(); ImGui.BeginDisabled(!model.Show); ImGui.Checkbox("Wire", ref model.Wireframe); ImGui.EndDisabled();
@@ -290,6 +289,8 @@ public class SnimGui
ImGui.SameLine(); ImGui.PushID(99);
ImGui.VSliderFloat("", box with { X = width }, ref model.MorphTime, 0.0f, 1.0f, "", ImGuiSliderFlags.AlwaysClamp);
ImGui.PopID(); ImGui.PopStyleVar();
+ ImGui.Spacing();
+ ImGui.Text($"Time: {model.MorphTime:P}%");
}
}
else
@@ -330,10 +331,10 @@ public class SnimGui
ImGui.DragFloat("X", ref model.Transforms[model.SelectedInstance].Position.X, speed, 0f, 0f, "%.2f m");
ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Y", ref model.Transforms[model.SelectedInstance].Position.Y, speed, 0f, 0f, "%.2f m");
+ ImGui.DragFloat("Y", ref model.Transforms[model.SelectedInstance].Position.Z, speed, 0f, 0f, "%.2f m");
ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Z", ref model.Transforms[model.SelectedInstance].Position.Z, speed, 0f, 0f, "%.2f m");
+ ImGui.DragFloat("Z", ref model.Transforms[model.SelectedInstance].Position.Y, speed, 0f, 0f, "%.2f m");
ImGui.PopID();
ImGui.TreePop();
@@ -344,10 +345,10 @@ public class SnimGui
{
ImGui.PushID(2);
ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("X", ref model.Transforms[model.SelectedInstance].Rotation.Pitch, .5f, 0f, 0f, "%.1f°");
+ ImGui.DragFloat("X", ref model.Transforms[model.SelectedInstance].Rotation.Roll, .5f, 0f, 0f, "%.1f°");
ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Y", ref model.Transforms[model.SelectedInstance].Rotation.Roll, .5f, 0f, 0f, "%.1f°");
+ ImGui.DragFloat("Y", ref model.Transforms[model.SelectedInstance].Rotation.Pitch, .5f, 0f, 0f, "%.1f°");
ImGui.SetNextItemWidth(width);
ImGui.DragFloat("Z", ref model.Transforms[model.SelectedInstance].Rotation.Yaw, .5f, 0f, 0f, "%.1f°");
@@ -363,10 +364,10 @@ public class SnimGui
ImGui.DragFloat("X", ref model.Transforms[model.SelectedInstance].Scale.X, speed, 0f, 0f, "%.3f");
ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Y", ref model.Transforms[model.SelectedInstance].Scale.Y, speed, 0f, 0f, "%.3f");
+ ImGui.DragFloat("Y", ref model.Transforms[model.SelectedInstance].Scale.Z, speed, 0f, 0f, "%.3f");
ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Z", ref model.Transforms[model.SelectedInstance].Scale.Z, speed, 0f, 0f, "%.3f");
+ ImGui.DragFloat("Z", ref model.Transforms[model.SelectedInstance].Scale.Y, speed, 0f, 0f, "%.3f");
ImGui.PopID();
ImGui.TreePop();
@@ -496,8 +497,28 @@ public class SnimGui
ImGui.TextColored(color, text);
}
- private void DrawSquareTexture(Texture texture, Vector2 size) =>
+ private void DrawSquareTexture(Texture texture, Vector2 size)
+ {
ImGui.Image(texture?.GetPointer() ?? IntPtr.Zero, size, Vector2.Zero, Vector2.One, Vector4.One, new Vector4(1, 1, 1, .5f));
+ if (texture == null) return;
+
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text($"Type: ({texture.Format}) {texture.Type}:{texture.Name}");
+ ImGui.Text($"Texture: {texture.Path}");
+ ImGui.Text($"Imported: {texture.ImportedWidth}x{texture.ImportedHeight}");
+ ImGui.Text($"Mip Used: {texture.Width}x{texture.Height}");
+ ImGui.Spacing();
+ ImGui.TextDisabled(texture.Label);
+ ImGui.EndTooltip();
+ }
+ if (ImGui.IsItemClicked())
+ {
+ ImGui.SetClipboardText(Creator.Utils.FixPath(texture.Path));
+ texture.Label = "(?) Path Copied to Clipboard";
+ }
+ }
private void Theme(ImGuiStylePtr style)
{
diff --git a/FModel/Views/Snooper/Texture.cs b/FModel/Views/Snooper/Texture.cs
index 44545e27..8cf00fb3 100644
--- a/FModel/Views/Snooper/Texture.cs
+++ b/FModel/Views/Snooper/Texture.cs
@@ -1,10 +1,10 @@
using System;
using System.Windows;
using CUE4Parse.UE4.Assets.Exports.Texture;
+using CUE4Parse.UE4.Objects.Core.Math;
using OpenTK.Graphics.OpenGL4;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
-using SkiaSharp;
namespace FModel.Views.Snooper;
@@ -90,6 +90,23 @@ public class Texture : IDisposable
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
}
+ public Texture(FLinearColor color) : this(TextureType.Normal)
+ {
+ Type = "LinearColor";
+ Name = color.Hex;
+ Width = 1;
+ Height = 1;
+ Bind(TextureUnit.Texture0);
+
+ GL.TexImage2D(_target, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Rgba, PixelType.Float, ref color);
+ GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear);
+ GL.TexParameter(_target, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
+ GL.TexParameter(_target, TextureParameterName.TextureBaseLevel, 0);
+ GL.TexParameter(_target, TextureParameterName.TextureMaxLevel, 8);
+
+ GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
+ }
+
public Texture(string[] textures) : this(TextureType.Cubemap)
{
Bind(TextureUnit.Texture0);
diff --git a/FModel/Views/Snooper/Transform.cs b/FModel/Views/Snooper/Transform.cs
index 1b748081..1e1b3b9a 100644
--- a/FModel/Views/Snooper/Transform.cs
+++ b/FModel/Views/Snooper/Transform.cs
@@ -1,4 +1,4 @@
-using System.Numerics;
+using System.Numerics;
using CUE4Parse.UE4.Objects.Core.Math;
namespace FModel.Views.Snooper;
@@ -10,16 +10,14 @@ public class Transform
get => new ();
}
- public FVector Position = FVector.ZeroVector;
+ public FVector Position = FVector.ZeroVector.ToMapVector();
public FRotator Rotation = FRotator.ZeroRotator;
- public FVector Scale = FVector.OneVector;
+ public FVector Scale = FVector.OneVector.ToMapVector();
public Matrix4x4 Matrix =>
- Matrix4x4.Identity *
- Matrix4x4.CreateFromYawPitchRoll(
- Helper.DegreesToRadians(Rotation.Yaw),
- Helper.DegreesToRadians(Rotation.Pitch),
- Helper.DegreesToRadians(Rotation.Roll)) *
Matrix4x4.CreateScale(Scale) *
+ Matrix4x4.CreateRotationX(Helper.DegreesToRadians(Rotation.Roll)) *
+ Matrix4x4.CreateRotationY(Helper.DegreesToRadians(-Rotation.Yaw)) *
+ Matrix4x4.CreateRotationZ(Helper.DegreesToRadians(Rotation.Pitch)) *
Matrix4x4.CreateTranslation(Position);
}