diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index 9f143a85..80dd9cc6 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -130,7 +130,6 @@
-
diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs
index 88c73acc..563c3b27 100644
--- a/FModel/MainWindow.xaml.cs
+++ b/FModel/MainWindow.xaml.cs
@@ -79,7 +79,7 @@ public partial class MainWindow
#if DEBUG
await _threadWorkerView.Begin(_ =>
_applicationView.CUE4Parse.Extract(
- "/Game/Gadgets/Assets/VinderTech_GliderChute/Glider_Mark_II/Meshes/Glider_Mark_II.uasset"));
+ "FortniteGame/Content/Environments/Props/Winter/Meshes/SM_ChristmasTree_Llama.uasset"));
#endif
}
diff --git a/FModel/Views/Snooper/Camera.cs b/FModel/Views/Snooper/Camera.cs
index e41094f0..9dbaf5d8 100644
--- a/FModel/Views/Snooper/Camera.cs
+++ b/FModel/Views/Snooper/Camera.cs
@@ -1,5 +1,6 @@
using System;
using System.Numerics;
+using Serilog;
namespace FModel.Views.Snooper;
@@ -9,16 +10,15 @@ public class Camera
public Vector3 Direction { get; private set; }
public Vector3 Up = Vector3.UnitY;
- public float AspectRatio { get; }
public float Yaw { get; set; } = -90f;
- public float Pitch { get; set; }
- public float Zoom = 45f;
+ public float Pitch { get; set; } = 0f;
+ public float Zoom { get; set; } = 45f;
+ public float AspectRatio => 16f / 9f;
- public Camera(Vector3 position, Vector3 direction, float aspectRatio = 16f / 9f)
+ public Camera(Vector3 position, Vector3 direction)
{
Position = position;
Direction = direction;
- AspectRatio = aspectRatio;
// trigonometric math to calculate the cam's yaw/pitch based on position and direction to look
var yaw = MathF.Atan((-Position.X - Direction.X) / (Position.Z - Direction.Z));
@@ -40,7 +40,7 @@ public class Camera
//We don't want to be able to look behind us by going over our head or under our feet so make sure it stays within these bounds
Pitch = Math.Clamp(Pitch, -89f, 89f);
- Direction = Vector3.Normalize(CalculateDirection());
+ CalculateDirection();
}
public Matrix4x4 GetViewMatrix()
@@ -53,12 +53,22 @@ public class Camera
return Matrix4x4.CreatePerspectiveFieldOfView(Helper.DegreesToRadians(Zoom), AspectRatio, 0.1f, 100.0f);
}
- private Vector3 CalculateDirection()
+ public void CalculateDirection()
{
var direction = Vector3.Zero;
- direction.X = MathF.Cos(Helper.DegreesToRadians(Yaw)) * MathF.Cos(Helper.DegreesToRadians(Pitch));
- direction.Y = MathF.Sin(Helper.DegreesToRadians(Pitch));
- direction.Z = MathF.Sin(Helper.DegreesToRadians(Yaw)) * MathF.Cos(Helper.DegreesToRadians(Pitch));
- return direction;
+ var yaw = Helper.DegreesToRadians(Yaw);
+ var pitch = Helper.DegreesToRadians(Pitch);
+ direction.X = MathF.Cos(yaw) * MathF.Cos(pitch);
+ direction.Y = MathF.Sin(pitch);
+ direction.Z = MathF.Sin(yaw) * MathF.Cos(pitch);
+ Direction = Vector3.Normalize(direction);
+ }
+
+ private void Loge()
+ {
+ Log.Logger.Information("Position {Position}", Position);
+ Log.Logger.Information("Direction {Direction}", Direction);
+ Log.Logger.Information("Yaw {Yaw}", Yaw);
+ Log.Logger.Information("Pitch {Pitch}", Pitch);
}
}
diff --git a/FModel/Views/Snooper/Mesh.cs b/FModel/Views/Snooper/Model.cs
similarity index 67%
rename from FModel/Views/Snooper/Mesh.cs
rename to FModel/Views/Snooper/Model.cs
index 70869128..9755d97a 100644
--- a/FModel/Views/Snooper/Mesh.cs
+++ b/FModel/Views/Snooper/Model.cs
@@ -1,15 +1,12 @@
using System;
using System.Linq;
using System.Numerics;
-using CUE4Parse.UE4.Assets.Exports.Material;
-using CUE4Parse.UE4.Assets.Exports.Texture;
using CUE4Parse_Conversion.Meshes.PSK;
-using CUE4Parse_Conversion.Textures;
using Silk.NET.OpenGL;
namespace FModel.Views.Snooper;
-public class Mesh : IDisposable
+public class Model : IDisposable
{
private uint _handle;
private GL _gl;
@@ -18,28 +15,27 @@ public class Mesh : IDisposable
private BufferObject _vbo;
private VertexArrayObject _vao;
- private Shader _shader;
- private Texture[] _albedoMap;
- // private Texture _normalMap;
-
private const int _vertexSize = 8; // Position + Normals + UV
private const uint _faceSize = 3; // just so we don't have to do .Length
private readonly uint[] _facesIndex = { 1, 0, 2 };
+ private Shader _shader;
+
public uint[] Indices;
public float[] Vertices;
- public CMaterialParams[] Params;
+ public Section[] Sections;
- public Mesh(CBaseMeshLod lod, CMeshVertex[] vertices)
+ public Model(CBaseMeshLod lod, CMeshVertex[] vertices)
{
var sections = lod.Sections.Value;
- Params = new CMaterialParams[sections.Length];
+ Sections = new Section[sections.Length];
Indices = new uint[sections.Sum(section => section.NumFaces * _faceSize)];
Vertices = new float[Indices.Length * _vertexSize];
for (var s = 0; s < sections.Length; s++)
{
var section = sections[s];
+ Sections[s] = new Section((uint) section.NumFaces * _faceSize, section.FirstIndex, section);
for (uint face = 0; face < section.NumFaces; face++)
{
foreach (var f in _facesIndex)
@@ -58,15 +54,9 @@ public class Mesh : IDisposable
Vertices[index * _vertexSize + 6] = vert.UV.U;
Vertices[index * _vertexSize + 7] = vert.UV.V;
- Indices[index] = (uint) index;
+ Indices[index] = i;
}
}
-
- Params[s] = new CMaterialParams();
- if (section.Material != null && section.Material.TryLoad(out var material) && material is UMaterialInterface unrealMaterial)
- {
- unrealMaterial.GetParams(Params[s]);
- }
}
}
@@ -76,6 +66,8 @@ public class Mesh : IDisposable
_handle = _gl.CreateProgram();
+ _shader = new Shader(_gl);
+
_ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer);
_vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer);
_vao = new VertexArrayObject(_gl, _vbo, _ebo);
@@ -84,20 +76,13 @@ public class Mesh : IDisposable
_vao.VertexAttributePointer(1, 3, VertexAttribPointerType.Float, _vertexSize, 3); // normals
_vao.VertexAttributePointer(2, 2, VertexAttribPointerType.Float, _vertexSize, 6); // uv
- _shader = new Shader(_gl);
-
- _albedoMap = new Texture[Params.Length];
- for (int i = 0; i < _albedoMap.Length; i++)
+ for (int section = 0; section < Sections.Length; section++)
{
- if (Params[i].Diffuse is UTexture2D { IsVirtual: false } diffuse && diffuse.GetFirstMip() is { } mip)
- {
- TextureDecoder.DecodeTexture(mip, diffuse.Format, diffuse.isNormalMap, out var data, out _);
- _albedoMap[i] = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY);
- }
+ Sections[section].Setup(_gl);
}
}
- public unsafe void Bind(Camera camera)
+ public void Bind(Camera camera)
{
_vao.Bind();
@@ -106,15 +91,14 @@ public class Mesh : IDisposable
_shader.SetUniform("uModel", Matrix4x4.Identity);
_shader.SetUniform("uView", camera.GetViewMatrix());
_shader.SetUniform("uProjection", camera.GetProjectionMatrix());
- // _shader.SetUniform("viewPos", _camera.Position);
+ // _shader.SetUniform("viewPos", camera.Position);
- for (int i = 0; i < _albedoMap.Length; i++)
+ for (int section = 0; section < Sections.Length; section++)
{
- _shader.SetUniform("material.albedo", i);
- _albedoMap[i].Bind(TextureUnit.Texture0 + i);
- }
+ Sections[section].Bind(_shader);
- _gl.DrawElements(PrimitiveType.Triangles, (uint) Indices.Length, DrawElementsType.UnsignedInt, null);
+ _gl.DrawArrays(PrimitiveType.Triangles, Sections[section].FirstFaceIndex, Sections[section].FacesCount);
+ }
}
public void Dispose()
@@ -123,6 +107,10 @@ public class Mesh : IDisposable
_vbo.Dispose();
_vao.Dispose();
_shader.Dispose();
+ for (int section = 0; section < Sections.Length; section++)
+ {
+ Sections[section].Dispose();
+ }
_gl.DeleteProgram(_handle);
}
}
diff --git a/FModel/Views/Snooper/Section.cs b/FModel/Views/Snooper/Section.cs
new file mode 100644
index 00000000..95200a34
--- /dev/null
+++ b/FModel/Views/Snooper/Section.cs
@@ -0,0 +1,57 @@
+using System;
+using CUE4Parse.UE4.Assets.Exports.Material;
+using CUE4Parse.UE4.Assets.Exports.Texture;
+using CUE4Parse_Conversion.Meshes.PSK;
+using CUE4Parse_Conversion.Textures;
+using Silk.NET.OpenGL;
+
+namespace FModel.Views.Snooper;
+
+public class Section : IDisposable
+{
+ private uint _handle;
+ private GL _gl;
+
+ private Texture _albedoMap;
+ // private Texture _normalMap;
+
+ public uint FacesCount;
+ public int FirstFaceIndex;
+ public CMaterialParams Params;
+
+ public Section(uint facesCount, int firstFaceIndex, CMeshSection section)
+ {
+ FacesCount = facesCount;
+ FirstFaceIndex = firstFaceIndex;
+ Params = new CMaterialParams();
+ if (section.Material != null && section.Material.TryLoad(out var material) && material is UMaterialInterface unrealMaterial)
+ {
+ unrealMaterial.GetParams(Params);
+ }
+ }
+
+ public void Setup(GL gl)
+ {
+ _gl = gl;
+
+ _handle = _gl.CreateProgram();
+
+ if (Params.Diffuse is UTexture2D { IsVirtual: false } diffuse && diffuse.GetFirstMip() is { } mip)
+ {
+ TextureDecoder.DecodeTexture(mip, diffuse.Format, diffuse.isNormalMap, out var data, out _);
+ _albedoMap = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY);
+ }
+ }
+
+ public void Bind(Shader shader)
+ {
+ shader.SetUniform("material.albedo", 0);
+ _albedoMap.Bind(TextureUnit.Texture0);
+ }
+
+ public void Dispose()
+ {
+ _albedoMap.Dispose();
+ _gl.DeleteProgram(_handle);
+ }
+}
diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs
index 14e8bcbe..c8bf7f60 100644
--- a/FModel/Views/Snooper/Snooper.cs
+++ b/FModel/Views/Snooper/Snooper.cs
@@ -20,7 +20,7 @@ public class Snooper
private IKeyboard _keyboard;
private Vector2 _previousMousePosition;
- private Mesh[] _meshes;
+ private Model[] _models;
public int Width { get; }
public int Height { get; }
@@ -35,7 +35,6 @@ public class Snooper
var options = WindowOptions.Default;
options.Size = new Vector2D(Width, Height);
- options.Position = new Vector2D(Width, Height);
options.Title = "Snooper";
_window = Window.Create(options);
@@ -44,18 +43,18 @@ public class Snooper
_window.Render += OnRender;
_window.Closing += OnClose;
- _meshes = new Mesh[1];
+ _models = new Model[1];
switch (export)
{
case UStaticMesh st when st.TryConvert(out var mesh):
{
- _meshes[0] = new Mesh(mesh.LODs[0], mesh.LODs[0].Verts);
+ _models[0] = new Model(mesh.LODs[0], mesh.LODs[0].Verts);
SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
break;
}
case USkeletalMesh sk when sk.TryConvert(out var mesh):
{
- _meshes[0] = new Mesh(mesh.LODs[0], mesh.LODs[0].Verts);
+ _models[0] = new Model(mesh.LODs[0], mesh.LODs[0].Verts);
SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
break;
}
@@ -71,10 +70,6 @@ public class Snooper
private void SetupCamera(FBox box)
{
- // X Yaw Gauche Droite
- // Y Pitch Haut Bas
- // Z Avant Arrière
-
var center = box.GetCenter();
var position = new Vector3(0f, center.Z, box.Max.Y * 3);
_camera = new Camera(position, center);
@@ -95,9 +90,9 @@ public class Snooper
_gl = GL.GetApi(_window);
_gl.Enable(EnableCap.DepthTest);
- foreach (var mesh in _meshes)
+ foreach (var model in _models)
{
- mesh.Setup(_gl);
+ model.Setup(_gl);
}
}
@@ -106,9 +101,9 @@ public class Snooper
_gl.ClearColor(0.149f, 0.149f, 0.188f, 1.0f);
_gl.Clear((uint) ClearBufferMask.ColorBufferBit | (uint) ClearBufferMask.DepthBufferBit);
- foreach (var mesh in _meshes)
+ foreach (var model in _models)
{
- mesh.Bind(_camera);
+ model.Bind(_camera);
}
}
@@ -163,9 +158,9 @@ public class Snooper
private void OnClose()
{
- foreach (var mesh in _meshes)
+ foreach (var model in _models)
{
- mesh.Dispose();
+ model.Dispose();
}
}
diff --git a/FModel/Views/Snooper/Texture.cs b/FModel/Views/Snooper/Texture.cs
index d8d00013..7f9fd236 100644
--- a/FModel/Views/Snooper/Texture.cs
+++ b/FModel/Views/Snooper/Texture.cs
@@ -24,8 +24,6 @@ public class Texture : IDisposable
private void SetParameters()
{
- _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge);
- _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge);
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) GLEnum.LinearMipmapLinear);
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear);
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);