From 0295d47eba7f37c50198e622af57909a1d027750 Mon Sep 17 00:00:00 2001 From: 4sval Date: Tue, 13 Sep 2022 22:29:29 +0200 Subject: [PATCH] mesh morphing POC --- CUE4Parse | 2 +- FModel/MainWindow.xaml.cs | 2 +- FModel/Views/Snooper/Camera.cs | 16 +++++----- FModel/Views/Snooper/Model.cs | 38 +++++++++++++++++------ FModel/Views/Snooper/Section.cs | 12 ++----- FModel/Views/Snooper/SnimGui.cs | 28 ++++++++++++----- FModel/Views/Snooper/Snooper.cs | 4 +-- FModel/Views/Snooper/VertexArrayObject.cs | 4 +++ 8 files changed, 68 insertions(+), 38 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index 35f6d437..52871ba0 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 35f6d437eb0f03855d30265a6214794810868e6a +Subproject commit 52871ba0775c211473efb35805a39dd00586d10f diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index 8c311284..85091baf 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( - "FortniteGame/Content/Characters/Player/Male/Medium/Bodies/M_MED_StaminaCat/Meshes/M_MED_StaminaCat.uasset")); + "Hk_project/Content/Character/Zurg/Mesh/SKM_Zurg.uasset")); #endif } diff --git a/FModel/Views/Snooper/Camera.cs b/FModel/Views/Snooper/Camera.cs index 44a61043..4bdc3335 100644 --- a/FModel/Views/Snooper/Camera.cs +++ b/FModel/Views/Snooper/Camera.cs @@ -5,16 +5,16 @@ namespace FModel.Views.Snooper; public class Camera { - public Vector3 Position { get; set; } - public Vector3 Direction { get; private set; } + public Vector3 Position; + public Vector3 Direction; public Vector3 Up = Vector3.UnitY; - public float Yaw { get; set; } = -90f; - public float Pitch { get; set; } = 0f; - public float Zoom { get; set; } = 60f; - public float Speed { get; set; } = 1f; - public float Near { get; } = 0.01f; - public float Far { get; } = 100f; + public float Yaw = -90f; + public float Pitch = 0f; + public float Zoom = 60f; + public float Speed = 1f; + public float Near = 0.01f; + public float Far = 100f; public float AspectRatio => 16f / 9f; public Camera(Vector3 position, Vector3 direction, float near, float far, float speed) diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs index 2dc095dd..80af062e 100644 --- a/FModel/Views/Snooper/Model.cs +++ b/FModel/Views/Snooper/Model.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; using CUE4Parse.UE4.Assets.Exports; +using CUE4Parse.UE4.Assets.Exports.Animation; using CUE4Parse.UE4.Objects.Engine; +using CUE4Parse.UE4.Objects.UObject; using CUE4Parse_Conversion.Meshes.PSK; using Silk.NET.OpenGL; @@ -16,7 +18,8 @@ public class Model : IDisposable private BufferObject _ebo; private BufferObject _vbo; - private BufferObject _mvbo; + private BufferObject[] _morphVbo; + private BufferObject _matrixVbo; private VertexArrayObject _vao; private uint _vertexSize = 8; // Position + Normal + UV @@ -28,6 +31,7 @@ public class Model : IDisposable public readonly string Type; public readonly bool HasVertexColors; public readonly bool HasBones; + public readonly bool HasMorphTargets; public uint[] Indices; public float[] Vertices; public Section[] Sections; @@ -50,9 +54,11 @@ public class Model : IDisposable Transforms = new List(); Show = true; IsSavable = owner is not UWorld; + + _morphVbo = Array.Empty>(); } - public Model(UObject owner, string name, string type, CBaseMeshLod lod, CMeshVertex[] vertices, List skeleton = null, Transform transform = null) + public Model(UObject owner, string name, string type, CBaseMeshLod lod, CMeshVertex[] vertices, FPackageIndex[] morphTargets = null, List skeleton = null, Transform transform = null) : this(owner, name, type) { HasVertexColors = lod.VertexColors != null; @@ -62,6 +68,17 @@ public class Model : IDisposable HasBones = Skeleton != null; if (HasBones) _vertexSize += 8; // + BoneIds + BoneWeights + HasMorphTargets = morphTargets != null; + if (HasMorphTargets) + { + _morphVbo = new BufferObject[4 * morphTargets.Length]; // PositionDelta + SourceIdx + var morph = morphTargets[0].Load().MorphLODModels[0]; + foreach (var delta in morph.Vertices) + { + vertices[delta.SourceIdx].Position += delta.PositionDelta; + } + } + _vertexSize += 16; // + InstanceMatrix var sections = lod.Sections.Value; @@ -128,9 +145,9 @@ public class Model : IDisposable public void UpdateMatrix(int index) { - _mvbo.Bind(); - _mvbo.Update(index, Transforms[index].Matrix); - _mvbo.Unbind(); + _matrixVbo.Bind(); + _matrixVbo.Update(index, Transforms[index].Matrix); + _matrixVbo.Unbind(); } public void Setup(GL gl) @@ -155,14 +172,11 @@ public class Model : IDisposable var instanceMatrix = new Matrix4x4[TransformsCount]; for (var i = 0; i < instanceMatrix.Length; i++) instanceMatrix[i] = Transforms[i].Matrix; - _mvbo = new BufferObject(_gl, instanceMatrix, BufferTargetARB.ArrayBuffer); + _matrixVbo = new BufferObject(_gl, instanceMatrix, BufferTargetARB.ArrayBuffer); for (int section = 0; section < Sections.Length; section++) { - _vao.Bind(); _vao.BindInstancing(); - _vao.Unbind(); - Sections[section].Setup(_gl); } } @@ -214,7 +228,11 @@ public class Model : IDisposable { _ebo.Dispose(); _vbo.Dispose(); - _mvbo.Dispose(); + _matrixVbo.Dispose(); + for (int i = 0; i < _morphVbo.Length; i++) + { + _morphVbo[i].Dispose(); + } _vao.Dispose(); for (int section = 0; section < Sections.Length; section++) { diff --git a/FModel/Views/Snooper/Section.cs b/FModel/Views/Snooper/Section.cs index ec5d3549..fae44a0c 100644 --- a/FModel/Views/Snooper/Section.cs +++ b/FModel/Views/Snooper/Section.cs @@ -157,9 +157,6 @@ public class Section : IDisposable } } } - - Parameters.RoughnessValue = 1; - Parameters.MetallicValue = 1; break; } case FGame.ShooterGame: @@ -201,9 +198,6 @@ public class Section : IDisposable break; } - - Parameters.RoughnessValue = 1; - Parameters.MetallicValue = 1; break; } case FGame.Gameface: @@ -224,12 +218,12 @@ public class Section : IDisposable } } } - - Parameters.RoughnessValue = 1; - Parameters.MetallicValue = 1; break; } } + + Parameters.RoughnessValue = 1; + Parameters.MetallicValue = 1; } public void Bind(Shader shader, uint instanceCount) diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index 32b9ba1e..dc649568 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Numerics; using System.Windows; @@ -174,12 +174,13 @@ public class SnimGui : IDisposable if (ImGui.CollapsingHeader("Camera")) { PushStyleCompact(); - ImGui.Text($"Position: {camera.Position}"); - ImGui.Text($"Direction: {camera.Direction}"); - ImGui.Text($"Speed: {camera.Speed}"); - ImGui.Text($"Far: {camera.Far}"); - ImGui.Text($"Near: {camera.Near}"); - ImGui.Text($"Zoom: {camera.Zoom}"); + string[] modes = { "free cam", "orbital cam" }; + int selectedMode = 0; + ImGui.Combo("Projection", ref selectedMode, modes, modes.Length); + ImGui.DragFloat3("Position", ref camera.Position); + ImGui.DragFloat3("Direction", ref camera.Direction); + ImGui.DragFloat("Speed", ref camera.Speed, 0.01f); + ImGui.DragFloat("Zoom", ref camera.Zoom); PopStyleCompact(); } @@ -297,12 +298,25 @@ public class SnimGui : IDisposable ImGui.TableNextColumn(); if (ImGui.Selectable(section.Name, _selectedSection == i, ImGuiSelectableFlags.SpanAllColumns)) _selectedSection = i; + if (ImGui.BeginPopupContextItem()) + { + if (ImGui.Selectable("Swap")) + { + + } + ImGui.EndPopup(); + } ImGui.PopID(); } ImGui.EndTable(); PopStyleCompact(); ImGui.EndTabItem(); } + + if (ImGui.BeginTabItem("Shape Keys")) + { + ImGui.EndTabItem(); + } } ImGui.End(); diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs index 4009fe01..049c9239 100644 --- a/FModel/Views/Snooper/Snooper.cs +++ b/FModel/Views/Snooper/Snooper.cs @@ -112,7 +112,7 @@ public class Snooper var guid = Guid.NewGuid(); if (!_models.TryGetValue(guid, out _)) { - _models[guid] = new Model(export, sk.Name, sk.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, mesh.RefSkeleton); + _models[guid] = new Model(export, sk.Name, sk.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, sk.MorphTargets, mesh.RefSkeleton); SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO); } break; @@ -162,7 +162,7 @@ public class Snooper continue; } - model = new Model(export, m.Name, m.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, null, transform); + model = new Model(export, m.Name, m.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, null, null, transform); if (actor.TryGetAllValues(out FPackageIndex[] textureData, "TextureData")) { for (int j = 0; j < textureData.Length; j++) diff --git a/FModel/Views/Snooper/VertexArrayObject.cs b/FModel/Views/Snooper/VertexArrayObject.cs index 023e32cd..2c27ec92 100644 --- a/FModel/Views/Snooper/VertexArrayObject.cs +++ b/FModel/Views/Snooper/VertexArrayObject.cs @@ -40,6 +40,8 @@ public class VertexArrayObject : IDisposable where TVer public unsafe void BindInstancing() { + Bind(); + var vec4Size = (uint) sizeof(Vector4); _gl.EnableVertexAttribArray(6); _gl.VertexAttribPointer(6, 4, VertexAttribPointerType.Float, false, 4 * vec4Size, (void*)0); @@ -54,6 +56,8 @@ public class VertexArrayObject : IDisposable where TVer _gl.VertexAttribDivisor(7, 1); _gl.VertexAttribDivisor(8, 1); _gl.VertexAttribDivisor(9, 1); + + Unbind(); } public void Unbind()