mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2026-08-15 02:57:49 +04:00
animations and QOL
This commit is contained in:
@@ -60,6 +60,9 @@ public static class MshMeshDocumentImporter
|
||||
var indices = Msh0x06.ReadComponent(fs, archive);
|
||||
var batches = Msh0x0D.ReadComponent(fs, archive);
|
||||
var animationDescriptors = Msh0x08.ReadComponent(fs, archive);
|
||||
var animationMapComponent = TryReadAnimationMap(fs, archive, warnings);
|
||||
var animationMap = animationMapComponent?.Entries ?? [];
|
||||
var maxAnimationTime = animationMapComponent?.MaxAnimationTime ?? InferMaxAnimationTime(animationDescriptors);
|
||||
var restPoses = MshRestPoseBuilder.BuildRestPose(nodes, animationDescriptors);
|
||||
var names = TryReadNames(fs, archive, warnings);
|
||||
|
||||
@@ -121,7 +124,10 @@ public static class MshMeshDocumentImporter
|
||||
Normals = normals,
|
||||
Uvs = uvs,
|
||||
Indices = indices,
|
||||
Batches = batches
|
||||
Batches = batches,
|
||||
TransformKeyframes = animationDescriptors,
|
||||
AnimationMap = animationMap,
|
||||
MaxAnimationTime = maxAnimationTime
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -228,6 +234,27 @@ public static class MshMeshDocumentImporter
|
||||
}
|
||||
}
|
||||
|
||||
private static Msh0x13Component? TryReadAnimationMap(FileStream fs, NResArchive archive, ICollection<string> warnings)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Msh0x13.ReadComponent(fs, archive);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
warnings.Add($"MSH 0x13 animation map is unavailable: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int InferMaxAnimationTime(IReadOnlyList<MshTransformKeyframe> keyframes)
|
||||
{
|
||||
if (keyframes.Count == 0)
|
||||
return 0;
|
||||
|
||||
return (int)MathF.Ceiling(MathF.Max(0.0f, keyframes.Max(x => x.Time)));
|
||||
}
|
||||
|
||||
private static string ResolvePieceName(IReadOnlyList<string> names, int nodeIndex)
|
||||
{
|
||||
if (nodeIndex >= 0 && nodeIndex < names.Count && !string.IsNullOrWhiteSpace(names[nodeIndex]))
|
||||
|
||||
@@ -4,6 +4,7 @@ using NResUI.Rendering.Inspection;
|
||||
using NResUI.Rendering.Materials;
|
||||
using NResUI.Rendering.Viewport;
|
||||
using NResUI.Rendering.Viewport.Meshes;
|
||||
using NResUI.Rendering.Viewport.Msh;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace NResUI.Rendering.Import.Msh;
|
||||
@@ -26,18 +27,25 @@ public static class MshViewportMeshFactory
|
||||
var result = new List<ViewportPiece>();
|
||||
var modelGeometry = document.MshModelGeometry;
|
||||
var mshToViewportTransform = Matrix4x4.CreateRotationX(-MathF.PI * 0.5f);
|
||||
var poses = MshRestPoseBuilder.BuildPose(
|
||||
modelGeometry.Nodes,
|
||||
modelGeometry.TransformKeyframes,
|
||||
modelGeometry.AnimationMap,
|
||||
renderState.AnimationPoseMode,
|
||||
renderState.AnimationSampleTime);
|
||||
|
||||
foreach (var pieceInfo in document.Pieces)
|
||||
{
|
||||
if (!renderState.IsPieceVisible(pieceInfo.Id))
|
||||
continue;
|
||||
|
||||
var pieceTransform = poses[pieceInfo.Id].MeshSpaceTransform;
|
||||
var (pieceState, pieceLod) = ResolvePieceStateLod(document, pieceInfo, renderState);
|
||||
var slotIndex = pieceInfo.ResolveSlotIndex(pieceState, pieceLod);
|
||||
if (slotIndex == ushort.MaxValue || slotIndex >= modelGeometry.GeometrySlots.Slots.Count)
|
||||
{
|
||||
if (renderState.ShowEmptyPieces)
|
||||
AddEmptyPieceMarker(gl, result, pieceInfo, mshToViewportTransform, "No geometry slot for selected state/LOD");
|
||||
AddEmptyPieceMarker(gl, result, pieceInfo, pieceTransform, mshToViewportTransform, "No geometry slot for selected state/LOD");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -45,7 +53,7 @@ public static class MshViewportMeshFactory
|
||||
if (!slot.HasBatches)
|
||||
{
|
||||
if (renderState.ShowEmptyPieces)
|
||||
AddEmptyPieceMarker(gl, result, pieceInfo, mshToViewportTransform, "Geometry slot has no batches", slotIndex);
|
||||
AddEmptyPieceMarker(gl, result, pieceInfo, pieceTransform, mshToViewportTransform, "Geometry slot has no batches", slotIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -60,7 +68,7 @@ public static class MshViewportMeshFactory
|
||||
if (meshBuildResult == null)
|
||||
{
|
||||
if (renderState.ShowEmptyPieces)
|
||||
AddEmptyPieceMarker(gl, result, pieceInfo, mshToViewportTransform, "Geometry slot produced no valid triangles", slotIndex);
|
||||
AddEmptyPieceMarker(gl, result, pieceInfo, pieceTransform, mshToViewportTransform, "Geometry slot produced no valid triangles", slotIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -68,7 +76,7 @@ public static class MshViewportMeshFactory
|
||||
id: pieceInfo.Id,
|
||||
name: pieceInfo.Name,
|
||||
meshes: meshBuildResult.Meshes,
|
||||
localTransform: pieceInfo.MeshSpaceTransform * mshToViewportTransform,
|
||||
localTransform: pieceTransform * mshToViewportTransform,
|
||||
boundsMin: meshBuildResult.BoundsMin,
|
||||
boundsMax: meshBuildResult.BoundsMax,
|
||||
debugInfo: new ViewportPieceDebugInfo
|
||||
@@ -121,6 +129,7 @@ public static class MshViewportMeshFactory
|
||||
GL gl,
|
||||
List<ViewportPiece> pieces,
|
||||
MeshPieceInfo pieceInfo,
|
||||
Matrix4x4 pieceTransform,
|
||||
Matrix4x4 mshToViewportTransform,
|
||||
string reason,
|
||||
int geometrySlotIndex = -1)
|
||||
@@ -131,7 +140,7 @@ public static class MshViewportMeshFactory
|
||||
id: pieceInfo.Id,
|
||||
name: pieceInfo.Name,
|
||||
mesh: marker,
|
||||
localTransform: pieceInfo.MeshSpaceTransform * mshToViewportTransform,
|
||||
localTransform: pieceTransform * mshToViewportTransform,
|
||||
boundsMin: new Vector3(-0.35f, -0.35f, -0.35f),
|
||||
boundsMax: new Vector3(0.35f, 0.35f, 0.35f),
|
||||
debugInfo: new ViewportPieceDebugInfo
|
||||
|
||||
Reference in New Issue
Block a user