Skip to content

Commit

Permalink
fixed merge issues
Browse files Browse the repository at this point in the history
  • Loading branch information
kareking1 committed Sep 17, 2024
2 parents aaa7db4 + d50dd8c commit 96ce5e6
Show file tree
Hide file tree
Showing 220 changed files with 15,053 additions and 3,330 deletions.
168 changes: 166 additions & 2 deletions OpenKh.AssimpUtils/Kh2MdlxAssimp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
using OpenKh.Kh2;
using OpenKh.Kh2.Models;
using OpenKh.Kh2.Models.VIF;
using OpenKh.Kh2Anim.Mset;
using OpenKh.Kh2Anim.Mset.Interfaces;
using System.Numerics;
using OpenKh.Engine.Monogame.Helpers;

namespace OpenKh.AssimpUtils
{
Expand Down Expand Up @@ -120,7 +121,7 @@ public static Assimp.Scene getAssimpScene(MdlxParser mParser)
parentNode.Children.Add(boneNode);
}

MatrixRecursivity.ComputeMatrices(ref matricesToReverse, mParser);
OpenKh.Engine.Monogame.Helpers.MatrixRecursivity.ComputeMatrices(ref matricesToReverse, mParser);

foreach (Assimp.Mesh mesh in scene.Meshes)
{
Expand Down Expand Up @@ -242,6 +243,8 @@ public static Assimp.Scene getAssimpScene(ModelSkeletal model)
}

// BONES (Node hierarchy)
//Assimp.Node armatureNode = new Assimp.Node("Armature");
//scene.RootNode.Children.Add(armatureNode);
foreach (ModelCommon.Bone bone in model.Bones)
{
string boneName = "Bone" + bone.Index.ToString("D4");
Expand All @@ -250,6 +253,7 @@ public static Assimp.Scene getAssimpScene(ModelSkeletal model)
Assimp.Node parentNode;
if (bone.ParentIndex == -1)
{
//parentNode = armatureNode;
parentNode = scene.RootNode;
}
else
Expand Down Expand Up @@ -363,10 +367,170 @@ public static VifMesh getVifMeshFromAssimp(Assimp.Mesh mesh, Matrix4x4[] boneMat
return vifMesh;
}

public static void AddAnimation(Assimp.Scene assimpScene, Bar mdlxBar, AnimationBinary animation)
{
// Set basic data
Assimp.Animation assimpAnimation = new Assimp.Animation();
assimpAnimation.Name = "EXPORT";
assimpAnimation.DurationInTicks = animation.MotionFile.InterpolatedMotionHeader.FrameCount;
assimpAnimation.TicksPerSecond = animation.MotionFile.InterpolatedMotionHeader.FrameData.FramesPerSecond;
assimpScene.Animations.Add(assimpAnimation);

HashSet<float> keyframeTimes = animation.MotionFile.KeyTimes.ToHashSet();

// Get real duration
float minTime = 0;
float maxTime = 0;
foreach (var keyTime in keyframeTimes)
{
if(keyTime < minTime)
minTime = keyTime;
if(keyTime > maxTime)
maxTime = keyTime;
}
assimpAnimation.DurationInTicks = maxTime - minTime;

// Get absolute transformation matrices of the bones
Dictionary<float, Matrix4x4[]> frameMatrices = getMatricesForKeyFrames(mdlxBar, animation, keyframeTimes);

// Prepare channels per bone
Dictionary<int, Assimp.NodeAnimationChannel> animationChannelsPerBone = new Dictionary<int, Assimp.NodeAnimationChannel>();
for (int i = 0; i < animation.MotionFile.InterpolatedMotionHeader.BoneCount; i++)
{
Assimp.NodeAnimationChannel nodeAnimChannel = new Assimp.NodeAnimationChannel();
nodeAnimChannel.NodeName = "Bone" + i.ToString("D4");
animationChannelsPerBone.Add(i, nodeAnimChannel);
assimpAnimation.NodeAnimationChannels.Add(nodeAnimChannel);
}

// Get bone data
List<ModelCommon.Bone> modelBones = new List<ModelCommon.Bone>();
foreach (Bar.Entry barEntry in mdlxBar)
{
if(barEntry.Type == Bar.EntryType.Model)
{
ModelSkeletal modelFile = ModelSkeletal.Read(barEntry.Stream);
modelBones = modelFile.Bones;
break;
}
}

// Set channels
foreach (float keyTime in frameMatrices.Keys) // Frame
{
for (int j = 0; j < frameMatrices[keyTime].Length; j++) // Bone
{
Assimp.NodeAnimationChannel channel = animationChannelsPerBone[j];

Matrix4x4 currentFrameBoneMatrix = frameMatrices[keyTime][j];

// Transform to local
if (modelBones[j].ParentIndex != -1)
{
Matrix4x4.Invert(frameMatrices[keyTime][modelBones[j].ParentIndex], out Matrix4x4 invertedParent);
currentFrameBoneMatrix *= invertedParent;
}

Assimp.Matrix4x4 assimpMatrix = AssimpGeneric.ToAssimp(currentFrameBoneMatrix);
assimpMatrix.Decompose(out Assimp.Vector3D scaling, out Assimp.Quaternion rotation, out Assimp.Vector3D translation);

Assimp.VectorKey positionKey = new Assimp.VectorKey(keyTime / assimpAnimation.TicksPerSecond, translation);
Assimp.VectorKey scalingKey = new Assimp.VectorKey(keyTime / assimpAnimation.TicksPerSecond, new Assimp.Vector3D(RoundFloat(scaling.X), RoundFloat(scaling.Y), RoundFloat(scaling.Z)));
//Assimp.VectorKey scalingKey = new Assimp.VectorKey(keyTime / assimpAnimation.TicksPerSecond, scaling);
Assimp.QuaternionKey rotationKey = new Assimp.QuaternionKey(keyTime / assimpAnimation.TicksPerSecond, rotation);

// Ignore duplicates
if(channel.PositionKeys.Count > 0)
{
Assimp.VectorKey previousPositionKey = channel.PositionKeys[channel.PositionKeys.Count - 1];
Assimp.VectorKey previousScalingKey = channel.ScalingKeys[channel.ScalingKeys.Count - 1];
Assimp.QuaternionKey previousRotationKey = channel.RotationKeys[channel.RotationKeys.Count - 1];

if (!positionKey.Equals(previousPositionKey))
{
channel.PositionKeys.Add(positionKey);
}
if (!scalingKey.Equals(previousScalingKey))
{
channel.ScalingKeys.Add(scalingKey);
}
if (!rotationKey.Equals(previousRotationKey))
{
channel.RotationKeys.Add(rotationKey);
}
}
else
{
channel.PositionKeys.Add(positionKey);
channel.ScalingKeys.Add(scalingKey);
channel.RotationKeys.Add(rotationKey);
}
}
}

if(assimpScene.RootNode.FindNode("Armature") != null)
{
assimpAnimation.NodeAnimationChannels.Add(getArmatureChannel(keyframeTimes.ToArray()[0] / assimpAnimation.TicksPerSecond, assimpAnimation.DurationInTicks, animation.MotionFile.InterpolatedMotionHeader.FrameData.FramesPerSecond));
}
}

/****************
* UTILITIES
****************/

private static Vector3 ToVector3(Vector4 pos) => new Vector3(pos.X, pos.Y, pos.Z);
private static float RoundFloat(float value)
{
float reminder = value % 1;
if (reminder > 0.999999 && reminder < 0.999999999999)
{
return value - reminder + 1;
}
else if (reminder > 0 && reminder < 0.00001)
{
return value - reminder;
}
return value;
}

private static Assimp.NodeAnimationChannel getArmatureChannel(double startFrame, double endFrame, double framesPerSecond)
{
Assimp.NodeAnimationChannel armatureChannel = new Assimp.NodeAnimationChannel();
armatureChannel.NodeName = "Armature";

armatureChannel.PositionKeys.Add(new Assimp.VectorKey(startFrame / framesPerSecond, new Assimp.Vector3D(0,0,0)));
armatureChannel.ScalingKeys.Add(new Assimp.VectorKey(startFrame / framesPerSecond, new Assimp.Vector3D(1, 1, 1)));
armatureChannel.RotationKeys.Add(new Assimp.QuaternionKey(startFrame / framesPerSecond, new Assimp.Quaternion(1, 0, 0, 0)));

armatureChannel.PositionKeys.Add(new Assimp.VectorKey(endFrame / framesPerSecond, new Assimp.Vector3D(0, 0, 0)));
armatureChannel.ScalingKeys.Add(new Assimp.VectorKey(endFrame / framesPerSecond, new Assimp.Vector3D(1, 1, 1)));
armatureChannel.RotationKeys.Add(new Assimp.QuaternionKey(endFrame / framesPerSecond, new Assimp.Quaternion(1, 0, 0, 0)));

return armatureChannel;
}

// Generates the absolute transformation matrices for each bone for the given frames
// Makes use of IAnimMatricesProvider to generate the matrices
private static Dictionary<float, Matrix4x4[]> getMatricesForKeyFrames (Bar mdlxBar, AnimationBinary animation, HashSet<float> keyframeTimes)
{
// Mdlx as stream is required
MemoryStream modelStream = new MemoryStream();
Bar.Write(modelStream, mdlxBar);
modelStream.Position = 0;

// Calculate matrices
Dictionary<float, Matrix4x4[]> frameMatrices = new Dictionary<float, Matrix4x4[]>();
Bar anbBarFile = Bar.Read(animation.toStream());
foreach (float keyTime in keyframeTimes)
{
// I have no idea why this needs to be done for every frame but otherwise it won't work properly
AnbIndir currentAnb = new AnbIndir(anbBarFile);
IAnimMatricesProvider AnimMatricesProvider = currentAnb.GetAnimProvider(modelStream);
frameMatrices.Add(keyTime, AnimMatricesProvider.ProvideMatrices(keyTime));
modelStream.Position = 0;
}

return frameMatrices;
}
}
}
1 change: 1 addition & 0 deletions OpenKh.AssimpUtils/OpenKh.AssimpUtils.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<ProjectReference Include="..\OpenKh.Engine.MonoGame\OpenKh.Engine.MonoGame.csproj" />
<ProjectReference Include="..\OpenKh.Engine\OpenKh.Engine.csproj" />
<ProjectReference Include="..\OpenKh.Kh1\OpenKh.Kh1.csproj" />
<ProjectReference Include="..\OpenKh.Kh2AnimEmu\OpenKh.Kh2AnimEmu.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion OpenKh.Bbs/OpenKh.Bbs.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Expand Down
1 change: 0 additions & 1 deletion OpenKh.Bbs/Pmp.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.VisualBasic.CompilerServices;
using OpenKh.Common;
using OpenKh.Common.Utils;
using OpenKh.Imaging;
Expand Down
25 changes: 24 additions & 1 deletion OpenKh.Command.AnbMaker/Commands/AnbExCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
Expand All @@ -29,6 +30,7 @@ internal class AnbExCommand : IFbxSourceItemSelector, IMsetInjector

[Argument(1, Description = "anb output")]
public string Output { get; set; }
public string OutputMset { get; set; }

[Option(Description = "specify root armature node name", ShortName = "r")]
public string RootName { get; set; }
Expand Down Expand Up @@ -56,7 +58,7 @@ protected int OnExecute(CommandLineApplication app)
var logger = LogManager.GetLogger("InterpolatedMotionMaker");

Output = Path.GetFullPath(Output ?? Path.GetFileNameWithoutExtension(InputModel) + ".anb");

OutputMset = Path.GetFullPath(OutputMset ?? Path.GetFileNameWithoutExtension(InputModel) + ".mset");
Console.WriteLine($"Writing to: {Output}");

IEnumerable<BasicSourceMotion> parms;
Expand Down Expand Up @@ -117,12 +119,33 @@ protected int OnExecute(CommandLineApplication app)
Type = Bar.EntryType.Motion,
Name = "A999",
Stream = motionStream,
},
new Bar.Entry
{
Type = Bar.EntryType.MotionTriggers,
Name = "A999",
Stream = new MemoryStream() // Replace null with MemoryStream containing "0"
}
}
);

var msetBarStream = new MemoryStream();
Bar.Write(
msetBarStream,
new Bar.Entry[]
{
new Bar.Entry
{
Type = Bar.EntryType.Anb,
Name = "A999",
Stream = anbBarStream
}
}
);

File.WriteAllBytes(Output, anbBarStream.ToArray());
File.WriteAllBytes(Output + ".raw", motionStream.ToArray());
File.WriteAllBytes(OutputMset, msetBarStream.ToArray());

logger.Debug($"Motion data generation successful");

Expand Down
55 changes: 49 additions & 6 deletions OpenKh.Command.AnbMaker/Utils/Builder/InterpolatedMotionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,21 @@ float FixPos(float value)

new ChannelProvider
{
type = Channel.ROTATATION_X,
type = Channel.ROTATION_X,
jointFlags = JointFlags.HasRotation,
keys = hit.RotationXKeys,
fixValue = it => it,
},
new ChannelProvider
{
type = Channel.ROTATATION_Y,
type = Channel.ROTATION_Y,
jointFlags = JointFlags.HasRotation,
keys = hit.RotationYKeys,
fixValue = it => it,
},
new ChannelProvider
{
type = Channel.ROTATATION_Z,
type = Channel.ROTATION_Z,
jointFlags = JointFlags.HasRotation,
keys = hit.RotationZKeys,
fixValue = it => it,
Expand Down Expand Up @@ -175,6 +175,8 @@ float FixPos(float value)
},
};

fixRotations(channels);

var jointFlag = JointFlags.None;

foreach (var channel in channels)
Expand Down Expand Up @@ -234,9 +236,9 @@ out Vector3 translation
initialPoseDict[new InitialPoseKey(boneIdx, Channel.SCALE_X)] = FixScalingValue(scale.X);
initialPoseDict[new InitialPoseKey(boneIdx, Channel.SCALE_Y)] = FixScalingValue(scale.Y);
initialPoseDict[new InitialPoseKey(boneIdx, Channel.SCALE_Z)] = FixScalingValue(scale.Z);
initialPoseDict[new InitialPoseKey(boneIdx, Channel.ROTATATION_X)] = rotation.X;
initialPoseDict[new InitialPoseKey(boneIdx, Channel.ROTATATION_Y)] = rotation.Y;
initialPoseDict[new InitialPoseKey(boneIdx, Channel.ROTATATION_Z)] = rotation.Z;
initialPoseDict[new InitialPoseKey(boneIdx, Channel.ROTATION_X)] = rotation.X;
initialPoseDict[new InitialPoseKey(boneIdx, Channel.ROTATION_Y)] = rotation.Y;
initialPoseDict[new InitialPoseKey(boneIdx, Channel.ROTATION_Z)] = rotation.Z;
initialPoseDict[new InitialPoseKey(boneIdx, Channel.TRANSLATION_X)] = FixPosValue(translation.X);
initialPoseDict[new InitialPoseKey(boneIdx, Channel.TRANSLATION_Y)] = FixPosValue(translation.Y);
initialPoseDict[new InitialPoseKey(boneIdx, Channel.TRANSLATION_Z)] = FixPosValue(translation.Z);
Expand Down Expand Up @@ -387,5 +389,46 @@ public int Compare(InitialPoseKey? left, InitialPoseKey? right)
return diff;
}
}

// Fix by Some1fromthedark
private float unwrapAngle(float previous_angle, float current_angle)
{
float diff = current_angle - previous_angle;
if (diff < -Math.PI)
{
while (diff < -Math.PI)
{
current_angle += (float)(2 * Math.PI);
diff = current_angle - previous_angle;
}
}
else if (diff > Math.PI)
{
while (Math.PI < diff)
{
current_angle -= (float)(2 * Math.PI);
diff = current_angle - previous_angle;
}
}
return current_angle;
}

private void fixRotations(ChannelProvider[] channels)
{
foreach (ChannelProvider channel in channels)
{
if (channel.type == Channel.ROTATION_X ||
channel.type == Channel.ROTATION_Y ||
channel.type == Channel.ROTATION_Z)
{
float previousAngle = 0;
foreach (var k in channel.keys)
{
k.Value = unwrapAngle(previousAngle, k.Value);
previousAngle = k.Value;
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion OpenKh.Command.Bdxio/OpenKh.Command.Bdxio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" />
<PackageReference Include="NLog" Version="5.3.2" />
<PackageReference Include="YamlDotNet" Version="15.1.2" />
<PackageReference Include="YamlDotNet" Version="15.3.0" />
<PackageReference Include="Xe.BinaryMapper" Version="1.5.2" />
<PackageReference Include="Antlr4.Runtime.Standard" Version="4.13.1" />

Expand Down
Loading

0 comments on commit 96ce5e6

Please sign in to comment.