mirror of
https://github.com/4sval/FModel.git
synced 2026-09-07 00:56:29 -05:00
more world lights
This commit is contained in:
Submodule CUE4Parse updated: d5a1610bbd...b02fb8c67e
@@ -1,4 +1,4 @@
|
||||
#version 460 core
|
||||
#version 460 core
|
||||
|
||||
layout (location = 1) in vec3 vPos;
|
||||
layout (location = 2) in vec3 vNormal;
|
||||
@@ -12,8 +12,8 @@ layout (location = 9) in mat4 vInstanceMatrix;
|
||||
layout (location = 13) in vec3 vMorphTargetPos;
|
||||
layout (location = 14) in vec3 vMorphTargetTangent;
|
||||
|
||||
//const int MAX_BONES = 0;
|
||||
//const int MAX_BONE_INFLUENCE = 0;
|
||||
//const int MAX_BONES = 140;
|
||||
//const int MAX_BONE_INFLUENCE = 4;
|
||||
|
||||
uniform mat4 uView;
|
||||
uniform mat4 uProjection;
|
||||
@@ -33,13 +33,14 @@ void main()
|
||||
vec3 tangent = mix(vTangent, vMorphTargetTangent, uMorphTime);
|
||||
// for(int i = 0 ; i < MAX_BONE_INFLUENCE; i++)
|
||||
// {
|
||||
// if(vBoneIds[i] == -1) continue;
|
||||
// if(vBoneIds[i] >= MAX_BONES)
|
||||
// int boneIndex = int(vBoneIds[i]);
|
||||
// if(boneIndex == -1) continue;
|
||||
// if(boneIndex >= MAX_BONES)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// vec4 localPos = uFinalBonesMatrix[int(vBoneIds[i])] * pos;
|
||||
// vec4 localPos = uFinalBonesMatrix[boneIndex] * pos;
|
||||
// pos += localPos * vBoneWeights[i];
|
||||
// }
|
||||
|
||||
|
||||
@@ -36,6 +36,22 @@ public abstract class Light : IDisposable
|
||||
public float Intensity;
|
||||
public bool IsSetup;
|
||||
|
||||
public Light(Texture icon, UObject light)
|
||||
{
|
||||
Transform = new Transform
|
||||
{
|
||||
Position = light.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO,
|
||||
Rotation = light.GetOrDefault("RelativeRotation", FRotator.ZeroRotator).Quaternion(),
|
||||
Scale = light.GetOrDefault("RelativeScale3D", FVector.OneVector)
|
||||
};
|
||||
|
||||
Model = Guid.NewGuid();
|
||||
Icon = icon;
|
||||
|
||||
Color = light.GetOrDefault("LightColor", new FColor(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
Intensity = light.GetOrDefault("Intensity", 1.0f);
|
||||
}
|
||||
|
||||
public Light(FGuid model, Texture icon, UObject parent, UObject light, Transform transform)
|
||||
{
|
||||
Transform = new Transform
|
||||
|
||||
@@ -12,9 +12,19 @@ public class PointLight : Light
|
||||
public float Linear;
|
||||
public float Quadratic;
|
||||
|
||||
public PointLight(Texture icon, UObject point) : base(icon, point)
|
||||
{
|
||||
if (!point.TryGetValue(out float radius, "SourceRadius", "AttenuationRadius"))
|
||||
radius = 1.0f;
|
||||
|
||||
radius *= Constants.SCALE_DOWN_RATIO;
|
||||
Linear = 4.5f / radius;
|
||||
Quadratic = 75.0f / MathF.Pow(radius, 2.0f);
|
||||
}
|
||||
|
||||
public PointLight(FGuid model, Texture icon, UObject parent, UObject point, Transform transform) : base(model, icon, parent, point, transform)
|
||||
{
|
||||
if (!point.TryGetValue(out float radius, "AttenuationRadius", "SourceRadius"))
|
||||
if (!point.TryGetValue(out float radius, "SourceRadius", "AttenuationRadius"))
|
||||
radius = 1.0f;
|
||||
|
||||
radius *= Constants.SCALE_DOWN_RATIO;
|
||||
|
||||
@@ -12,9 +12,19 @@ public class SpotLight : Light
|
||||
public float InnerConeAngle;
|
||||
public float OuterConeAngle;
|
||||
|
||||
public SpotLight(Texture icon, UObject spot) : base(icon, spot)
|
||||
{
|
||||
if (!spot.TryGetValue(out Attenuation, "SourceRadius", "AttenuationRadius"))
|
||||
Attenuation = 1.0f;
|
||||
|
||||
Attenuation *= Constants.SCALE_DOWN_RATIO;
|
||||
InnerConeAngle = spot.GetOrDefault("InnerConeAngle", 50.0f);
|
||||
OuterConeAngle = spot.GetOrDefault("OuterConeAngle", 60.0f);
|
||||
}
|
||||
|
||||
public SpotLight(FGuid model, Texture icon, UObject parent, UObject spot, Transform transform) : base(model, icon, parent, spot, transform)
|
||||
{
|
||||
if (!spot.TryGetValue(out Attenuation, "AttenuationRadius", "SourceRadius"))
|
||||
if (!spot.TryGetValue(out Attenuation, "SourceRadius", "AttenuationRadius"))
|
||||
Attenuation = 1.0f;
|
||||
|
||||
Attenuation *= Constants.SCALE_DOWN_RATIO;
|
||||
|
||||
@@ -2,57 +2,54 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using CUE4Parse_Conversion.Animations;
|
||||
using CUE4Parse.UE4.Assets.Exports.Animation;
|
||||
using CUE4Parse.UE4.Objects.Core.Math;
|
||||
|
||||
namespace FModel.Views.Snooper.Models.Animations;
|
||||
|
||||
public class Animation : IDisposable
|
||||
{
|
||||
public float CurrentTime;
|
||||
public int CurrentTime;
|
||||
public float DeltaTime;
|
||||
public CAnimSet CurrentAnimation;
|
||||
public Transform[] FinalBonesMatrix;
|
||||
|
||||
public Animation(CAnimSet anim, Dictionary<string, int> nameToIndex, Dictionary<int, Transform> indexToTransform)
|
||||
public Animation(CAnimSet anim)
|
||||
{
|
||||
CurrentTime = 0f;
|
||||
CurrentTime = 0;
|
||||
CurrentAnimation = anim;
|
||||
|
||||
FinalBonesMatrix = new Transform[anim.TrackBoneNames.Length];
|
||||
for (int i = 0; i < FinalBonesMatrix.Length; i++)
|
||||
{
|
||||
if (!nameToIndex.TryGetValue(anim.TrackBoneNames[i].Text, out var boneIndex) ||
|
||||
!indexToTransform.TryGetValue(boneIndex, out var boneTransform))
|
||||
{
|
||||
boneTransform = Transform.Identity;
|
||||
}
|
||||
|
||||
FinalBonesMatrix[i] = Transform.Identity;
|
||||
FinalBonesMatrix[i].Relation = boneTransform.Matrix;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAnimation(float deltaTime)
|
||||
public void UpdateAnimation(FMeshBoneInfo[] boneInfos, ref Dictionary<int, Transform> bonesTransformByIndex)
|
||||
{
|
||||
DeltaTime = deltaTime;
|
||||
if (CurrentAnimation != null)
|
||||
{
|
||||
// CurrentTime = deltaTime;
|
||||
CalculateBoneTransform();
|
||||
CalculateBoneTransform(boneInfos, ref bonesTransformByIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void CalculateBoneTransform()
|
||||
public void CalculateBoneTransform(FMeshBoneInfo[] boneInfos, ref Dictionary<int, Transform> bonesTransformByIndex)
|
||||
{
|
||||
var sequence = CurrentAnimation.Sequences[0];
|
||||
for (int boneIndex = 0; boneIndex < FinalBonesMatrix.Length; boneIndex++)
|
||||
for (int boneIndex = 0; boneIndex < boneInfos.Length; boneIndex++)
|
||||
{
|
||||
var boneOrientation = FQuat.Identity;
|
||||
var bonePosition = FVector.ZeroVector;
|
||||
var boneScale = FVector.OneVector;
|
||||
sequence.Tracks[boneIndex].GetBonePosition(CurrentTime, sequence.NumFrames, false, ref bonePosition, ref boneOrientation);
|
||||
if (CurrentTime < sequence.Tracks[boneIndex].KeyScale.Length)
|
||||
boneScale = sequence.Tracks[boneIndex].KeyScale[CurrentTime];
|
||||
|
||||
FinalBonesMatrix[boneIndex].Rotation = boneOrientation;
|
||||
FinalBonesMatrix[boneIndex].Position = bonePosition * Constants.SCALE_DOWN_RATIO;
|
||||
if (!bonesTransformByIndex.TryGetValue(boneInfos[boneIndex].ParentIndex, out var parentTransform))
|
||||
parentTransform = new Transform { Relation = Matrix4x4.Identity };
|
||||
|
||||
bonesTransformByIndex[boneIndex] = new Transform
|
||||
{
|
||||
Relation = parentTransform.Matrix,
|
||||
Rotation = boneOrientation,
|
||||
Position = bonePosition * Constants.SCALE_DOWN_RATIO,
|
||||
Scale = boneScale
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public class Skeleton : IDisposable
|
||||
public readonly USkeleton UnrealSkeleton;
|
||||
public readonly FReferenceSkeleton ReferenceSkeleton;
|
||||
public readonly Dictionary<string, int> BonesIndexByName;
|
||||
public readonly Dictionary<int, Transform> BonesTransformByIndex;
|
||||
public Dictionary<int, Transform> BonesTransformByIndex;
|
||||
public readonly bool IsLoaded;
|
||||
|
||||
public Animation Anim;
|
||||
@@ -27,22 +27,23 @@ public class Skeleton : IDisposable
|
||||
public Skeleton(FPackageIndex package, FReferenceSkeleton referenceSkeleton, Transform transform) : this()
|
||||
{
|
||||
UnrealSkeleton = package.Load<USkeleton>();
|
||||
if (UnrealSkeleton == null) return;
|
||||
IsLoaded = UnrealSkeleton != null;
|
||||
if (!IsLoaded) return;
|
||||
|
||||
ReferenceSkeleton = referenceSkeleton ?? UnrealSkeleton.ReferenceSkeleton;
|
||||
BonesIndexByName = ReferenceSkeleton.FinalNameToIndexMap;
|
||||
BonesTransformByIndex = new Dictionary<int, Transform>();
|
||||
UpdateBoneMatrices(transform.Matrix);
|
||||
IsLoaded = true;
|
||||
}
|
||||
|
||||
public void SetAnimation(CAnimSet anim)
|
||||
{
|
||||
Anim = new Animation(anim, BonesIndexByName, BonesTransformByIndex);
|
||||
Anim = new Animation(anim);
|
||||
}
|
||||
|
||||
public void UpdateBoneMatrices(Matrix4x4 matrix)
|
||||
{
|
||||
if (!IsLoaded) return;
|
||||
foreach (var boneIndex in BonesIndexByName.Values)
|
||||
{
|
||||
var bone = ReferenceSkeleton.FinalRefBonePose[boneIndex];
|
||||
@@ -69,9 +70,10 @@ public class Skeleton : IDisposable
|
||||
public void SetUniform(Shader shader)
|
||||
{
|
||||
if (!IsLoaded) return;
|
||||
for (var i = 0; i < Anim?.FinalBonesMatrix.Length; i++)
|
||||
Anim?.UpdateAnimation(ReferenceSkeleton.FinalRefBoneInfo, ref BonesTransformByIndex);
|
||||
foreach ((int boneIndex, Transform boneTransform) in BonesTransformByIndex)
|
||||
{
|
||||
shader.SetUniform($"uFinalBonesMatrix[{i}]", Anim.FinalBonesMatrix[i].Matrix);
|
||||
shader.SetUniform($"uFinalBonesMatrix[{boneIndex}]", boneTransform.Matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -362,6 +362,7 @@ public class Model : IDisposable
|
||||
shader.SetUniform("uMorphTime", MorphTime);
|
||||
if (!outline)
|
||||
{
|
||||
// if (HasSkeleton) Skeleton.SetUniform(shader);
|
||||
shader.SetUniform("uUvCount", UvCount);
|
||||
shader.SetUniform("uHasVertexColors", HasVertexColors);
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ public class Renderer : IDisposable
|
||||
|
||||
Services.ApplicationService.ApplicationView.Status.UpdateStatusLabel($"{original.Name} ... {i}/{length}");
|
||||
WorldCamera(actor);
|
||||
// WorldLight(actor);
|
||||
WorldLight(actor);
|
||||
WorldMesh(actor, transform);
|
||||
AdditionalWorlds(actor, transform.Matrix, cancellationToken);
|
||||
}
|
||||
@@ -250,10 +250,22 @@ public class Renderer : IDisposable
|
||||
|
||||
private void WorldLight(UObject actor)
|
||||
{
|
||||
// if (!actor.TryGetValue(out FPackageIndex lightComponent, "LightComponent") ||
|
||||
// lightComponent.Load() is not { } lightObject) return;
|
||||
//
|
||||
// Cache.Lights.Add(new PointLight(Cache.Icons["pointlight"], lightObject, FVector.ZeroVector));
|
||||
if (!actor.TryGetValue(out FPackageIndex lightComponent, "LightComponent") ||
|
||||
lightComponent.Load() is not { } lightObject) return;
|
||||
|
||||
switch (actor.ExportType)
|
||||
{
|
||||
case "PointLight":
|
||||
Options.Lights.Add(new PointLight(Options.Icons["pointlight"], lightObject));
|
||||
break;
|
||||
case "SpotLight":
|
||||
Options.Lights.Add(new SpotLight(Options.Icons["spotlight"], lightObject));
|
||||
break;
|
||||
case "RectLight":
|
||||
case "SkyLight":
|
||||
case "DirectionalLight":
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void WorldMesh(UObject actor, Transform transform)
|
||||
|
||||
@@ -158,11 +158,14 @@ public class SnimGui
|
||||
{
|
||||
for (int i = 0; i < s.Renderer.Options.Lights.Count; i++)
|
||||
{
|
||||
var id = $"[{i}] {s.Renderer.Options.Models[s.Renderer.Options.Lights[i].Model].Name}";
|
||||
var light = s.Renderer.Options.Lights[i];
|
||||
var id = s.Renderer.Options.TryGetModel(light.Model, out var lightModel) ? lightModel.Name : "None";
|
||||
|
||||
id += $"##{i}";
|
||||
if (ImGui.TreeNode(id) && ImGui.BeginTable(id, 2))
|
||||
{
|
||||
s.Renderer.Options.SelectModel(s.Renderer.Options.Lights[i].Model);
|
||||
s.Renderer.Options.Lights[i].ImGuiLight();
|
||||
s.Renderer.Options.SelectModel(light.Model);
|
||||
light.ImGuiLight();
|
||||
ImGui.EndTable();
|
||||
ImGui.TreePop();
|
||||
}
|
||||
@@ -341,8 +344,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
||||
_saver.Value = model.TrySave(out _saver.Label, out _saver.Path);
|
||||
s.WindowShouldFreeze(false);
|
||||
}
|
||||
ImGui.BeginDisabled(true);
|
||||
// ImGui.BeginDisabled(!model.HasSkeleton);
|
||||
ImGui.BeginDisabled(!model.HasSkeleton);
|
||||
if (ImGui.Selectable("Animate"))
|
||||
{
|
||||
s.Renderer.Options.AnimateMesh(true);
|
||||
@@ -444,6 +446,10 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
||||
Layout("Guid");ImGui.Text($" : {s.Renderer.Options.SelectedModel.ToString(EGuidFormats.UniqueObjectGuid)}");
|
||||
if (model.HasSkeleton)
|
||||
{
|
||||
if (model.Skeleton.Anim != null)
|
||||
{
|
||||
ImGui.DragInt("Time", ref model.Skeleton.Anim.CurrentTime, 1, 0, 110);
|
||||
}
|
||||
Layout("Skeleton");ImGui.Text($" : {model.Skeleton.UnrealSkeleton.Name}");
|
||||
Layout("Bones");ImGui.Text($" : x{model.Skeleton.UnrealSkeleton.BoneTree.Length}");
|
||||
}
|
||||
|
||||
@@ -74,4 +74,6 @@ public class Transform
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => Matrix.Translation.ToString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user