mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
Merge branch 'dev' of https://github.com/4sval/FModel into dev
This commit is contained in:
commit
8867f4bf0c
|
|
@ -85,7 +85,10 @@ public partial class MainWindow
|
|||
#if DEBUG
|
||||
// await _threadWorkerView.Begin(cancellationToken =>
|
||||
// _applicationView.CUE4Parse.Extract(cancellationToken,
|
||||
// "FortniteGame/Content/Environments/Asteria/Props/Coastal/Coastal_Boat_B/Meshes/SM_Coastal_Boat_B.uasset"));
|
||||
// "fortnitegame/Content/Characters/Player/Female/Large/Bodies/F_LRG_BunnyBR/Meshes/F_LRG_BunnyBR.uasset"));
|
||||
// await _threadWorkerView.Begin(cancellationToken =>
|
||||
// _applicationView.CUE4Parse.Extract(cancellationToken,
|
||||
// "FortniteGame/Content/Environments/Helios/Props/GlacierHotel/GlacierHotel_Globe_A/Meshes/SM_GlacierHotel_Globe_A.uasset"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using CUE4Parse.UE4.Objects.Core.Math;
|
||||
using CUE4Parse.UE4.Objects.PhysicsEngine;
|
||||
using CUE4Parse.UE4.Objects.UObject;
|
||||
using FModel.Views.Snooper.Buffers;
|
||||
using FModel.Views.Snooper.Shading;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
|
@ -9,16 +12,34 @@ namespace FModel.Views.Snooper.Models;
|
|||
|
||||
public class Collision : IDisposable
|
||||
{
|
||||
private const int Slices = 16;
|
||||
private const int Stacks = 8;
|
||||
private const float SectorStep = 2 * MathF.PI / Slices;
|
||||
private const float StackStep = MathF.PI / Stacks;
|
||||
|
||||
private readonly int[] _indexData;
|
||||
private readonly FVector[] _vertexData;
|
||||
private readonly Transform _transform;
|
||||
public readonly string LoweredBoneName;
|
||||
|
||||
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)
|
||||
private Collision()
|
||||
{
|
||||
_indexData = [];
|
||||
_vertexData = [];
|
||||
_transform = Transform.Identity;
|
||||
}
|
||||
|
||||
private Collision(FName boneName) : this()
|
||||
{
|
||||
LoweredBoneName = boneName.Text.ToLower();
|
||||
}
|
||||
|
||||
public Collision(FKConvexElem convexElems, FName boneName = default) : this(boneName)
|
||||
{
|
||||
_indexData = convexElems.IndexData;
|
||||
_vertexData = convexElems.VertexData;
|
||||
|
|
@ -30,6 +51,146 @@ public class Collision : IDisposable
|
|||
};
|
||||
}
|
||||
|
||||
public Collision(FKSphereElem sphereElem, FName boneName = default) : this(boneName)
|
||||
{
|
||||
_vertexData = new FVector[(Slices + 1) * (Stacks + 1)];
|
||||
for (var i = 0; i <= Stacks; i++)
|
||||
{
|
||||
var stackAngle = MathF.PI / 2 - i * StackStep;
|
||||
var xy = MathF.Cos(stackAngle);
|
||||
var z = MathF.Sin(stackAngle);
|
||||
|
||||
for (var j = 0; j <= Slices; j++)
|
||||
{
|
||||
var sectorAngle = j * SectorStep;
|
||||
var x = xy * MathF.Cos(sectorAngle);
|
||||
var y = xy * MathF.Sin(sectorAngle);
|
||||
_vertexData[i * (Slices + 1) + j] = new FVector(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
_indexData = new int[Stacks * Slices * 6];
|
||||
for (var i = 0; i < Stacks; i++)
|
||||
{
|
||||
for (var j = 0; j < Slices; j++)
|
||||
{
|
||||
var a = i * (Slices + 1) + j;
|
||||
var b = a + Slices + 1;
|
||||
_indexData[(i * Slices + j) * 6 + 0] = a;
|
||||
_indexData[(i * Slices + j) * 6 + 1] = b;
|
||||
_indexData[(i * Slices + j) * 6 + 2] = a + 1;
|
||||
_indexData[(i * Slices + j) * 6 + 3] = b;
|
||||
_indexData[(i * Slices + j) * 6 + 4] = b + 1;
|
||||
_indexData[(i * Slices + j) * 6 + 5] = a + 1;
|
||||
}
|
||||
}
|
||||
|
||||
_transform = new Transform
|
||||
{
|
||||
Position = sphereElem.Center * Constants.SCALE_DOWN_RATIO,
|
||||
Scale = new FVector(sphereElem.Radius)
|
||||
};
|
||||
}
|
||||
|
||||
public Collision(FKBoxElem boxElem, FName boneName = default) : this(boneName)
|
||||
{
|
||||
_vertexData =
|
||||
[
|
||||
new FVector(-boxElem.X, -boxElem.Y, -boxElem.Z),
|
||||
new FVector(boxElem.X, -boxElem.Y, -boxElem.Z),
|
||||
new FVector(boxElem.X, boxElem.Y, -boxElem.Z),
|
||||
new FVector(-boxElem.X, boxElem.Y, -boxElem.Z),
|
||||
new FVector(-boxElem.X, -boxElem.Y, boxElem.Z),
|
||||
new FVector(boxElem.X, -boxElem.Y, boxElem.Z),
|
||||
new FVector(boxElem.X, boxElem.Y, boxElem.Z),
|
||||
new FVector(-boxElem.X, boxElem.Y, boxElem.Z)
|
||||
];
|
||||
|
||||
_indexData =
|
||||
[
|
||||
0, 1, 2, 2, 3, 0,
|
||||
1, 5, 6, 6, 2, 1,
|
||||
5, 4, 7, 7, 6, 5,
|
||||
4, 0, 3, 3, 7, 4,
|
||||
3, 2, 6, 6, 7, 3,
|
||||
4, 5, 1, 1, 0, 4
|
||||
];
|
||||
|
||||
_transform = new Transform
|
||||
{
|
||||
Position = boxElem.Center * Constants.SCALE_DOWN_RATIO,
|
||||
Rotation = boxElem.Rotation.Quaternion(),
|
||||
Scale = new FVector(.5f)
|
||||
};
|
||||
}
|
||||
|
||||
public Collision(FKSphylElem sphylElem, FName boneName = default)
|
||||
: this(sphylElem.Length, [sphylElem.Radius, sphylElem.Radius], sphylElem.Center, sphylElem.Rotation, boneName) {}
|
||||
public Collision(FKTaperedCapsuleElem taperedCapsuleElem, FName boneName = default)
|
||||
: this(taperedCapsuleElem.Length, [taperedCapsuleElem.Radius1, taperedCapsuleElem.Radius0], taperedCapsuleElem.Center, taperedCapsuleElem.Rotation, boneName) {}
|
||||
|
||||
private Collision(float length, float[] radius, FVector center = default, FRotator rotator = default, FName boneName = default) : this(boneName)
|
||||
{
|
||||
int vLength = 0;
|
||||
int half = Slices / 2;
|
||||
int k2 = (Slices + 1) * (Stacks + 1);
|
||||
|
||||
_vertexData = new FVector[k2 + Slices + 1];
|
||||
for(int i = 0; i < 2; ++i)
|
||||
{
|
||||
float h = -length / 2.0f + i * length;
|
||||
int start = i == 0 ? Stacks / 2 : 0;
|
||||
int end = i == 0 ? Stacks : Stacks / 2;
|
||||
|
||||
for(int j = start; j <= end; ++j)
|
||||
{
|
||||
var stackAngle = MathF.PI / 2 - j * StackStep;
|
||||
var xy = radius[i] * MathF.Cos(stackAngle);
|
||||
var z = radius[i] * MathF.Sin(stackAngle) + h;
|
||||
|
||||
for(int k = 0; k <= Slices; ++k)
|
||||
{
|
||||
var sectorAngle = k * SectorStep;
|
||||
var x = xy * MathF.Cos(sectorAngle);
|
||||
var y = xy * MathF.Sin(sectorAngle);
|
||||
_vertexData[vLength++] = new FVector(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var indices = new List<int>();
|
||||
AddIndicesForSlices(indices, ref k2);
|
||||
indices.AddRange(new[] {0, k2, k2, k2 - half, half, half});
|
||||
AddIndicesForStacks(indices);
|
||||
half /= 2;
|
||||
indices.AddRange(new[] {half, k2 - half * 3, k2 - half * 3, half * 3, k2 - half, k2 - half});
|
||||
AddIndicesForStacks(indices, Stacks / 2);
|
||||
_indexData = indices.ToArray();
|
||||
|
||||
_transform = new Transform
|
||||
{
|
||||
Position = center * Constants.SCALE_DOWN_RATIO,
|
||||
Rotation = rotator.Quaternion()
|
||||
};
|
||||
}
|
||||
|
||||
private void AddIndicesForSlices(List<int> indices, ref int k2)
|
||||
{
|
||||
for(int k1 = 0; k1 < Slices; ++k1, ++k2)
|
||||
{
|
||||
indices.AddRange(new[] {k1, k1 + 1, k1 + 1, k2, k2 + 1, k2 + 1});
|
||||
}
|
||||
}
|
||||
|
||||
private void AddIndicesForStacks(List<int> indices, int start = 0)
|
||||
{
|
||||
for (int k1 = start; k1 < Stacks * Slices + Slices; k1 += Slices + 1)
|
||||
{
|
||||
if (k1 == Stacks / 2 * (Slices + 1) + start) continue;
|
||||
indices.AddRange(new[] {k1, k1 + Slices + 1, k1 + Slices + 1, k1 + Slices / 2, k1 + Slices / 2 + Slices + 1, k1 + Slices / 2 + Slices + 1});
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
_handle = GL.CreateProgram();
|
||||
|
|
@ -41,9 +202,9 @@ public class Collision : IDisposable
|
|||
_vao.Unbind();
|
||||
}
|
||||
|
||||
public void Render(Shader shader)
|
||||
public void Render(Shader shader, Matrix4x4 boneMatrix)
|
||||
{
|
||||
shader.SetUniform("uCollisionMatrix", _transform.Matrix);
|
||||
shader.SetUniform("uCollisionMatrix", _transform.Matrix * boneMatrix);
|
||||
|
||||
_vao.Bind();
|
||||
if (_indexData.Length > 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using CUE4Parse_Conversion.Meshes.PSK;
|
||||
using CUE4Parse.UE4.Assets.Exports.Animation;
|
||||
using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
|
||||
|
|
@ -52,7 +53,23 @@ public class SkeletalModel : UModel
|
|||
if (!skeletalBodySetup.TryLoad(out USkeletalBodySetup bodySetup) || bodySetup.AggGeom == null) continue;
|
||||
foreach (var convexElem in bodySetup.AggGeom.ConvexElems)
|
||||
{
|
||||
Collisions.Add(new Collision(convexElem));
|
||||
Collisions.Add(new Collision(convexElem, bodySetup.BoneName));
|
||||
}
|
||||
foreach (var sphereElem in bodySetup.AggGeom.SphereElems)
|
||||
{
|
||||
Collisions.Add(new Collision(sphereElem, bodySetup.BoneName));
|
||||
}
|
||||
foreach (var boxElem in bodySetup.AggGeom.BoxElems)
|
||||
{
|
||||
Collisions.Add(new Collision(boxElem, bodySetup.BoneName));
|
||||
}
|
||||
foreach (var sphylElem in bodySetup.AggGeom.SphylElems)
|
||||
{
|
||||
Collisions.Add(new Collision(sphylElem, bodySetup.BoneName));
|
||||
}
|
||||
foreach (var taperedCapsuleElem in bodySetup.AggGeom.TaperedCapsuleElems)
|
||||
{
|
||||
Collisions.Add(new Collision(taperedCapsuleElem, bodySetup.BoneName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,6 +125,26 @@ public class SkeletalModel : UModel
|
|||
Vao.Unbind();
|
||||
}
|
||||
|
||||
public override void RenderCollision(Shader shader)
|
||||
{
|
||||
base.RenderCollision(shader);
|
||||
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
||||
foreach (var collision in Collisions)
|
||||
{
|
||||
var boneMatrix = Matrix4x4.Identity;
|
||||
if (Skeleton.BonesByLoweredName.TryGetValue(collision.LoweredBoneName, out var bone))
|
||||
boneMatrix = Skeleton.GetBoneMatrix(bone);
|
||||
|
||||
collision.Render(shader, boneMatrix);
|
||||
}
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
}
|
||||
|
||||
public void Render(Shader shader)
|
||||
{
|
||||
shader.SetUniform("uMorphTime", MorphTime);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using CUE4Parse_Conversion.Meshes.PSK;
|
||||
using System.Numerics;
|
||||
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;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace FModel.Views.Snooper.Models;
|
||||
|
||||
|
|
@ -59,6 +61,22 @@ public class StaticModel : UModel
|
|||
{
|
||||
Collisions.Add(new Collision(convexElem));
|
||||
}
|
||||
foreach (var sphereElem in bodySetup.AggGeom.SphereElems)
|
||||
{
|
||||
Collisions.Add(new Collision(sphereElem));
|
||||
}
|
||||
foreach (var boxElem in bodySetup.AggGeom.BoxElems)
|
||||
{
|
||||
Collisions.Add(new Collision(boxElem));
|
||||
}
|
||||
foreach (var sphylElem in bodySetup.AggGeom.SphylElems)
|
||||
{
|
||||
Collisions.Add(new Collision(sphylElem));
|
||||
}
|
||||
foreach (var taperedCapsuleElem in bodySetup.AggGeom.TaperedCapsuleElems)
|
||||
{
|
||||
Collisions.Add(new Collision(taperedCapsuleElem));
|
||||
}
|
||||
}
|
||||
|
||||
Box = staticMesh.BoundingBox * Constants.SCALE_DOWN_RATIO;
|
||||
|
|
@ -68,4 +86,18 @@ public class StaticModel : UModel
|
|||
Sockets.Add(new Socket(socket));
|
||||
}
|
||||
}
|
||||
|
||||
public override void RenderCollision(Shader shader)
|
||||
{
|
||||
base.RenderCollision(shader);
|
||||
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
||||
foreach (var collision in Collisions)
|
||||
{
|
||||
collision.Render(shader, Matrix4x4.Identity);
|
||||
}
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,19 +305,10 @@ public abstract class UModel : IRenderableModel
|
|||
if (IsTwoSided) GL.Enable(EnableCap.CullFace);
|
||||
}
|
||||
|
||||
public void RenderCollision(Shader shader)
|
||||
public virtual void RenderCollision(Shader shader)
|
||||
{
|
||||
shader.SetUniform("uInstanceMatrix", GetTransform().Matrix);
|
||||
shader.SetUniform("uScaleDown", Constants.SCALE_DOWN_RATIO);
|
||||
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
||||
foreach (var collision in Collisions)
|
||||
{
|
||||
collision.Render(shader);
|
||||
}
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
}
|
||||
|
||||
public void Update(Options options)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user