convex collision preview

This commit is contained in:
Asval 2024-05-04 23:25:01 +02:00
parent d3ce4bedd7
commit ca95df2dd4
14 changed files with 148 additions and 21 deletions

@ -1 +1 @@
Subproject commit 38be126747f52c4a72f98d09de2d8073c4af750e
Subproject commit fb9413d0362457867e0c46c339ab3756c2b0a399

View File

@ -41,8 +41,6 @@ public partial class App
{
UserSettings.Default = JsonConvert.DeserializeObject<UserSettings>(
File.ReadAllText(UserSettings.FilePath), JsonNetSerializer.SerializerSettings);
/*if (UserSettings.Default.ShowChangelog) */MigrateV1Games();
}
catch
{
@ -143,17 +141,6 @@ public partial class App
e.Handled = true;
}
private void MigrateV1Games()
{
foreach ((var gameDir, var setting) in UserSettings.Default.ManualGames)
{
if (!Directory.Exists(gameDir)) continue;
UserSettings.Default.PerDirectory[gameDir] =
DirectorySettings.Default(setting.GameName, setting.GameDirectory, true, setting.OverridedGame, setting.AesKeys?.MainKey);
}
UserSettings.Default.ManualGames.Clear();
}
private string GetOperatingSystemProductName()
{
var productName = string.Empty;

View File

@ -116,6 +116,7 @@
<None Remove="Resources\light.vert" />
<None Remove="Resources\bone.frag" />
<None Remove="Resources\bone.vert" />
<None Remove="Resources\collision.vert" />
</ItemGroup>
<ItemGroup>
@ -141,6 +142,7 @@
<EmbeddedResource Include="Resources\light.vert" />
<EmbeddedResource Include="Resources\bone.frag" />
<EmbeddedResource Include="Resources\bone.vert" />
<EmbeddedResource Include="Resources\collision.vert" />
</ItemGroup>
<ItemGroup>

View File

@ -83,9 +83,9 @@ public partial class MainWindow
).ConfigureAwait(false);
#if DEBUG
await _threadWorkerView.Begin(cancellationToken =>
_applicationView.CUE4Parse.Extract(cancellationToken,
"ShooterGame/Content/Characters/Smonk/S0/3P/Models/TP_Smonk_S0_Skelmesh.uasset"));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
// "FortniteGame/Content/Environments/Asteria/Props/Coastal/Coastal_Boat_B/Meshes/SM_Coastal_Boat_B.uasset"));
#endif
}

View File

@ -0,0 +1,20 @@
#version 460 core
layout (location = 0) in vec3 vPos;
uniform mat4 uView;
uniform mat4 uProjection;
uniform mat4 uInstanceMatrix;
uniform mat4 uCollisionMatrix;
uniform float uScaleDown;
out vec3 fPos;
out vec3 fColor;
void main()
{
gl_PointSize = 7.5f;
gl_Position = uProjection * uView * uInstanceMatrix * uCollisionMatrix * vec4(vPos.xzy * uScaleDown, 1.0);
fPos = vec3(uInstanceMatrix * uCollisionMatrix * vec4(vPos.xzy * uScaleDown, 1.0));
fColor = vec3(1.0);
}

View File

@ -17,7 +17,6 @@ public class EndpointSettings : ViewModel
return new EndpointSettings[]
{
new("https://fortnitecentral.genxgames.gg/api/v1/aes", "$.['mainKey','dynamicKeys']"),
// new("https://fortnitecentral.genxgames.gg/api/v1/mappings", "$.[?(@.meta.compressionMethod=='Oodle')].['url','fileName']")
new("https://fortnitecentral.genxgames.gg/api/v1/mappings", "$.[0].['url','fileName']") // just get the first available, not just oodle! (Unfortunately not default except when resetting settings)
};
default:

View File

@ -399,6 +399,7 @@ public class CUE4ParseViewModel : ViewModel
else if (endpoint.IsValid)
{
var mappingsFolder = Path.Combine(UserSettings.Default.OutputDirectory, ".data");
if (endpoint.Path == "$.[?(@.meta.compressionMethod=='Oodle')].['url','fileName']") endpoint.Path = "$.[0].['url','fileName']";
var mappings = _apiEndpointView.DynamicApi.GetMappings(default, endpoint.Url, endpoint.Path);
if (mappings is { Length: > 0 })
{

View File

@ -0,0 +1,62 @@
using System;
using CUE4Parse.UE4.Objects.Core.Math;
using CUE4Parse.UE4.Objects.PhysicsEngine;
using FModel.Views.Snooper.Buffers;
using FModel.Views.Snooper.Shading;
using OpenTK.Graphics.OpenGL4;
namespace FModel.Views.Snooper.Models;
public class Collision : IDisposable
{
private readonly int[] _indexData;
private readonly FVector[] _vertexData;
private readonly Transform _transform;
private int _handle;
private BufferObject<int> _ebo { get; set; }
private BufferObject<FVector> _vbo { get; set; }
private VertexArrayObject<FVector, int> _vao { get; set; }
public Collision(FKConvexElem convexElems)
{
_indexData = convexElems.IndexData;
_vertexData = convexElems.VertexData;
_transform = new Transform
{
Position = convexElems.Transform.Translation * Constants.SCALE_DOWN_RATIO,
Rotation = convexElems.Transform.Rotation,
Scale = convexElems.Transform.Scale3D
};
}
public void Setup()
{
_handle = GL.CreateProgram();
_ebo = new BufferObject<int>(_indexData, BufferTarget.ElementArrayBuffer);
_vbo = new BufferObject<FVector>(_vertexData, BufferTarget.ArrayBuffer);
_vao = new VertexArrayObject<FVector, int>(_vbo, _ebo);
_vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 1, 0);
_vao.Unbind();
}
public void Render(Shader shader)
{
shader.SetUniform("uCollisionMatrix", _transform.Matrix);
_vao.Bind();
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
GL.DrawElements(PrimitiveType.Triangles, _ebo.Size, DrawElementsType.UnsignedInt, 0);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
_vao.Unbind();
}
public void Dispose()
{
_ebo?.Dispose();
_vbo?.Dispose();
_vao?.Dispose();
GL.DeleteProgram(_handle);
}
}

View File

@ -4,6 +4,7 @@ using CUE4Parse_Conversion.Meshes.PSK;
using CUE4Parse.UE4.Assets.Exports.Animation;
using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
using CUE4Parse.UE4.Objects.Core.Math;
using CUE4Parse.UE4.Objects.PhysicsEngine;
using CUE4Parse.UE4.Objects.UObject;
using FModel.Views.Snooper.Animations;
using FModel.Views.Snooper.Buffers;
@ -44,6 +45,18 @@ public class SkeletalModel : UModel
Sockets.Add(new Socket(socket));
}
if (export.PhysicsAsset.TryLoad(out UPhysicsAsset physicsAsset))
{
foreach (var skeletalBodySetup in physicsAsset.SkeletalBodySetups)
{
if (!skeletalBodySetup.TryLoad(out USkeletalBodySetup bodySetup)) continue;
foreach (var convexElem in bodySetup.AggGeom.ConvexElems)
{
Collisions.Add(new Collision(convexElem));
}
}
}
Morphs = new List<Morph>();
for (var i = 0; i < export.MorphTargets.Length; i++)
{

View File

@ -1,6 +1,7 @@
using CUE4Parse_Conversion.Meshes.PSK;
using CUE4Parse.UE4.Assets.Exports.Material;
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
using CUE4Parse.UE4.Objects.PhysicsEngine;
using FModel.Views.Snooper.Shading;
namespace FModel.Views.Snooper.Models;
@ -52,6 +53,14 @@ public class StaticModel : UModel
public StaticModel(UStaticMesh export, CStaticMesh staticMesh, Transform transform = null)
: base(export, staticMesh.LODs[LodLevel], export.Materials, staticMesh.LODs[LodLevel].Verts, staticMesh.LODs.Count, transform)
{
if (export.BodySetup.TryLoad(out UBodySetup bodySetup))
{
foreach (var convexElem in bodySetup.AggGeom.ConvexElems)
{
Collisions.Add(new Collision(convexElem));
}
}
Box = staticMesh.BoundingBox * Constants.SCALE_DOWN_RATIO;
for (int i = 0; i < export.Sockets.Length; i++)
{

View File

@ -60,6 +60,7 @@ public abstract class UModel : IRenderableModel
public FBox Box;
public readonly List<Socket> Sockets;
public readonly List<Collision> Collisions;
public Material[] Materials;
public bool IsTwoSided;
public bool IsProp;
@ -67,12 +68,14 @@ public abstract class UModel : IRenderableModel
public int VertexSize => _vertexAttributes.Where(x => x.Enabled).Sum(x => x.Size);
public bool HasVertexColors => _vertexAttributes[(int) EAttribute.Colors].Enabled;
public bool HasSockets => Sockets.Count > 0;
public bool HasCollisions => Collisions.Count > 0;
public int TransformsCount => Transforms.Count;
public bool IsSetup { get; set; }
public bool IsVisible { get; set; }
public bool IsSelected { get; set; }
public bool ShowWireframe { get; set; }
public bool ShowCollisions { get; set; }
public int SelectedInstance;
protected UModel()
@ -82,6 +85,7 @@ public abstract class UModel : IRenderableModel
Box = new FBox(new FVector(-2f), new FVector(2f));
Sockets = new List<Socket>();
Collisions = new List<Collision>();
Transforms = new List<Transform>();
}
@ -95,6 +99,7 @@ public abstract class UModel : IRenderableModel
Box = new FBox(new FVector(-2f), new FVector(2f));
Sockets = new List<Socket>();
Collisions = new List<Collision>();
Transforms = new List<Transform>();
Attachments = new Attachment(Name);
@ -209,6 +214,11 @@ public abstract class UModel : IRenderableModel
Materials[i].Setup(options, broken ? 1 : UvCount);
}
foreach (var collision in Collisions)
{
collision.Setup();
}
if (options.Models.Count == 1 && Sections.All(x => !x.Show))
{
IsVisible = true;
@ -294,6 +304,16 @@ public abstract class UModel : IRenderableModel
if (IsTwoSided) GL.Enable(EnableCap.CullFace);
}
public void RenderCollision(Shader shader)
{
shader.SetUniform("uInstanceMatrix", GetTransform().Matrix);
shader.SetUniform("uScaleDown", Constants.SCALE_DOWN_RATIO);
foreach (var collision in Collisions)
{
collision.Render(shader);
}
}
public void Update(Options options)
{
MatrixVbo.Bind();
@ -381,6 +401,11 @@ public abstract class UModel : IRenderableModel
socket?.Dispose();
}
Sockets.Clear();
foreach (var collision in Collisions)
{
collision?.Dispose();
}
Collisions.Clear();
GL.DeleteProgram(Handle);
}

View File

@ -46,6 +46,7 @@ public class Renderer : IDisposable
private Shader _outline;
private Shader _light;
private Shader _bone;
private Shader _collision;
private bool _saveCameraMode;
public bool ShowSkybox;
@ -227,6 +228,7 @@ public class Renderer : IDisposable
_outline = new Shader("outline");
_light = new Shader("light");
_bone = new Shader("bone");
_collision = new Shader("collision", "bone");
Picking.Setup();
Options.SetupModelsAndLights();
@ -272,6 +274,11 @@ public class Renderer : IDisposable
_bone.Render(viewMatrix, projMatrix);
skeletalModel.RenderBones(_bone);
}
else if (selected.ShowCollisions)
{
_collision.Render(viewMatrix, projMatrix);
selected.RenderCollision(_collision);
}
_outline.Render(viewMatrix, CameraOp.Position, projMatrix);
selected.Render(_outline, Color == VertexColor.TextureCoordinates ? Options.Icons["checker"] : null, true);
@ -642,6 +649,7 @@ public class Renderer : IDisposable
_outline?.Dispose();
_light?.Dispose();
_bone?.Dispose();
_collision?.Dispose();
Picking?.Dispose();
Options?.Dispose();
}

View File

@ -14,12 +14,12 @@ public class Shader : IDisposable
public Shader() : this("default") {}
public Shader(string name)
public Shader(string name1, string name2 = null)
{
_handle = GL.CreateProgram();
var v = LoadShader(ShaderType.VertexShader, $"{name}.vert");
var f = LoadShader(ShaderType.FragmentShader, $"{name}.frag");
var v = LoadShader(ShaderType.VertexShader, $"{name1}.vert");
var f = LoadShader(ShaderType.FragmentShader, $"{name2 ?? name1}.frag");
GL.AttachShader(_handle, v);
GL.AttachShader(_handle, f);
GL.LinkProgram(_handle);

View File

@ -421,6 +421,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
s.Renderer.Options.SelectModel(guid);
if (ImGui.MenuItem("Show", null, model.IsVisible)) model.IsVisible = !model.IsVisible;
if (ImGui.MenuItem("Wireframe", null, model.ShowWireframe)) model.ShowWireframe = !model.ShowWireframe;
if (ImGui.MenuItem("Collisions", null, model.ShowCollisions, model.HasCollisions)) model.ShowCollisions = !model.ShowCollisions;
ImGui.Separator();
if (ImGui.MenuItem("Save"))
{