Skip to content

Commit

Permalink
Adding ResetAnimationsBones. It looks like the system is half working
Browse files Browse the repository at this point in the history
  • Loading branch information
MrScautHD committed Dec 14, 2024
1 parent ac9561b commit 2a4a16a
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 33 deletions.
29 changes: 20 additions & 9 deletions src/Bliss.Test/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Bliss.CSharp.Graphics.Rendering.Passes;
using Bliss.CSharp.Interact;
using Bliss.CSharp.Interact.Contexts;
using Bliss.CSharp.Interact.Keyboards;
using Bliss.CSharp.Logging;
using Bliss.CSharp.Textures;
using Bliss.CSharp.Transformations;
Expand Down Expand Up @@ -54,6 +55,9 @@ public class Game : Disposable {
private Cam3D _cam3D;
private Model _playerModel;
private Model _planeModel;

private int _frameCount;
private bool _playingAnim;

public Game(GameSettings settings) {

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'MainWindow' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'GraphicsDevice' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'CommandList' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'FullScreenRenderPass' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'FullScreenTexture' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_spriteBatch' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 62 in src/Bliss.Test/Game.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_primitiveBatch' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
Instance = this;
Expand Down Expand Up @@ -156,17 +160,16 @@ protected virtual void Update() {
}

protected virtual void AfterUpdate() { }

public int test;


protected virtual void FixedUpdate() {
test++;
if (Input.IsKeyDown(KeyboardKey.H)) {
this._playingAnim = true;
this._frameCount++;

if (test >= this._playerModel.Animations[2].FrameCount) {
test = 0;
if (this._frameCount >= this._playerModel.Animations[0].FrameCount) {
this._frameCount = 0;
}
}

Logger.Error(this._playerModel.Animations[2].FrameCount+ "");
}

protected virtual void Draw(GraphicsDevice graphicsDevice, CommandList commandList) {
Expand All @@ -183,9 +186,17 @@ protected virtual void Draw(GraphicsDevice graphicsDevice, CommandList commandLi
if (this._cam3D.GetFrustum().ContainsBox(this._planeModel.BoundingBox)) {
this._planeModel.Draw(commandList, this.FullScreenTexture.Framebuffer.OutputDescription, new Transform(), Color.White);
}

if (Input.IsKeyPressed(KeyboardKey.G)) {
this._playerModel.ResetAnimationBones(commandList);
this._playingAnim = false;
Logger.Error("RESET ANIM");
}

if (this._cam3D.GetFrustum().ContainsBox(this._playerModel.BoundingBox)) {
this._playerModel.UpdateAnimationBones(commandList, this._playerModel.Animations[2], test);
if (this._playingAnim) {
this._playerModel.UpdateAnimationBones(commandList, this._playerModel.Animations[0], this._frameCount);
}
this._playerModel.Draw(commandList, this.FullScreenTexture.Framebuffer.OutputDescription, new Transform() { Translation = new Vector3(0, 0.05F, 0)}, Color.Blue);
}

Expand Down
47 changes: 27 additions & 20 deletions src/Bliss/CSharp/Geometry/Animations/MeshAmateurBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Assimp;
using Bliss.CSharp.Geometry.Animations.Bones;
using Bliss.CSharp.Geometry.Conversions;
using Bliss.CSharp.Logging;
using AMatrix4x4 = Assimp.Matrix4x4;
using Matrix4x4 = System.Numerics.Matrix4x4;
using AQuaternion = Assimp.Quaternion;
Expand Down Expand Up @@ -77,11 +78,11 @@ private Dictionary<int, BoneInfo[]> SetupBoneInfos(ModelAnimation animation) {
private void UpdateChannel(Node node, ModelAnimation animation, int frame, AMatrix4x4 parentTransform) {
AMatrix4x4 nodeTransformation = AMatrix4x4.Identity;

if (GetChannel(node, animation, out NodeAnimationChannel? channel)) {
if (this.GetChannel(node, animation, out NodeAnimationChannel? channel)) {
AMatrix4x4 scale = this.InterpolateScale(channel!, animation, frame);
AMatrix4x4 rotation = this.InterpolateRotation(channel!, animation, frame);
AMatrix4x4 translation = this.InterpolateTranslation(channel!, animation, frame);

nodeTransformation = scale * rotation * translation;
}

Expand All @@ -103,16 +104,16 @@ private void UpdateChannel(Node node, ModelAnimation animation, int frame, AMatr
}

/// <summary>
/// Interpolates the translation of a node for a given frame in an animation channel.
/// Interpolates the translation transformation at a specific frame using the provided animation channel and animation data.
/// </summary>
/// <param name="channel">The <see cref="NodeAnimationChannel"/> containing the position keys for translation.</param>
/// <param name="animation">The <see cref="ModelAnimation"/> providing the animation metadata.</param>
/// <param name="frame">The current frame index for which the translation is being interpolated.</param>
/// <returns>An <see cref="AMatrix4x4"/> representing the interpolated translation transformation for the node.</returns>
/// <param name="channel">The <see cref="NodeAnimationChannel"/> containing position keys for the node.</param>
/// <param name="animation">The <see cref="ModelAnimation"/> containing the animation data, including timing information.</param>
/// <param name="frame">The current frame for which the translation is being interpolated.</param>
/// <returns>An <see cref="Assimp.Matrix4x4"/> representing the interpolated translation transformation for the given frame.</returns>
private AMatrix4x4 InterpolateTranslation(NodeAnimationChannel channel, ModelAnimation animation, int frame) {
double frameTime = frame / 60.0F * animation.TicksPerSecond;
Vector3D position;

if (channel.PositionKeyCount == 1) {
position = channel.PositionKeys[0].Value;
}
Expand All @@ -124,7 +125,7 @@ private AMatrix4x4 InterpolateTranslation(NodeAnimationChannel channel, ModelAni
break;
}
}

VectorKey currentFrame = channel.PositionKeys[(int) frameIndex];
VectorKey nextFrame = channel.PositionKeys[(int) ((frameIndex + 1) % channel.PositionKeyCount)];

Expand All @@ -134,17 +135,17 @@ private AMatrix4x4 InterpolateTranslation(NodeAnimationChannel channel, ModelAni
Vector3D end = nextFrame.Value;
position = start + (float) delta * (end - start);
}

return AMatrix4x4.FromTranslation(position);
}

/// <summary>
/// Interpolates the rotation of a node for a given animation frame using spherical linear interpolation (Slerp).
/// Interpolates the rotation transformation for a given node animation channel at a specified frame.
/// </summary>
/// <param name="channel">The <see cref="NodeAnimationChannel"/> containing rotation keyframes for the node.</param>
/// <param name="animation">The <see cref="ModelAnimation"/> defining the animation to be processed.</param>
/// <param name="frame">The current animation frame index.</param>
/// <returns>A <see cref="AMatrix4x4"/> representing the interpolated rotation transformation for the specified frame.</returns>
/// <param name="channel">The <see cref="NodeAnimationChannel"/> containing the rotation keyframes for the node.</param>
/// <param name="animation">The <see cref="ModelAnimation"/> object defining the overall animation data.</param>
/// <param name="frame">The current frame for which the rotation needs to be interpolated.</param>
/// <returns>An <see cref="AMatrix4x4"/> representing the interpolated rotation transformation matrix for the specified frame.</returns>
private AMatrix4x4 InterpolateRotation(NodeAnimationChannel channel, ModelAnimation animation, int frame) {
double frameTime = frame / 60.0F * animation.TicksPerSecond;
AQuaternion rotation;
Expand All @@ -164,17 +165,24 @@ private AMatrix4x4 InterpolateRotation(NodeAnimationChannel channel, ModelAnimat
QuaternionKey currentFrame = channel.RotationKeys[(int) frameIndex];
QuaternionKey nextFrame = channel.RotationKeys[(int) ((frameIndex + 1) % channel.RotationKeyCount)];

double delta = (frameTime - (float) currentFrame.Time) / (float) (nextFrame.Time - currentFrame.Time);
double delta = (frameTime - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);

AQuaternion start = currentFrame.Value;
AQuaternion end = nextFrame.Value;
rotation = AQuaternion.Slerp(start, end, (float) delta);
rotation.Normalize();
}

return rotation.GetMatrix();
}

/// <summary>
/// Computes the interpolated scale transformation for a given animation channel at a specific frame.
/// </summary>
/// <param name="channel">The <see cref="NodeAnimationChannel"/> containing scaling keyframes.</param>
/// <param name="animation">The <see cref="ModelAnimation"/> associated with the animation data.</param>
/// <param name="frame">The current frame of the animation for which the scale transformation is calculated.</param>
/// <returns>An <see cref="AMatrix4x4"/> representing the interpolated scale transformation at the specified frame.</returns>
private AMatrix4x4 InterpolateScale(NodeAnimationChannel channel, ModelAnimation animation, int frame) {
double frameTime = frame / 60.0F * animation.TicksPerSecond;
Vector3D scale;
Expand All @@ -184,7 +192,6 @@ private AMatrix4x4 InterpolateScale(NodeAnimationChannel channel, ModelAnimation
}
else {
uint frameIndex = 0;

for (uint i = 0; i < channel.ScalingKeyCount - 1; i++) {
if (frameTime < channel.ScalingKeys[(int) (i + 1)].Time) {
frameIndex = i;
Expand All @@ -195,14 +202,14 @@ private AMatrix4x4 InterpolateScale(NodeAnimationChannel channel, ModelAnimation
VectorKey currentFrame = channel.ScalingKeys[(int)frameIndex];
VectorKey nextFrame = channel.ScalingKeys[(int)((frameIndex + 1) % channel.ScalingKeyCount)];

double delta = (frameTime - (float) currentFrame.Time) / (float) (nextFrame.Time - currentFrame.Time);
double delta = (frameTime - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);

Vector3D start = currentFrame.Value;
Vector3D end = nextFrame.Value;

scale = start + (float) delta * (end - start);
}

return AMatrix4x4.FromScaling(scale);
}

Expand Down
16 changes: 15 additions & 1 deletion src/Bliss/CSharp/Geometry/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,24 @@ public Mesh(GraphicsDevice graphicsDevice, Material material, Vertex3D[]? vertic
public void UpdateAnimationBones(CommandList commandList, ModelAnimation animation, int frame) {
if (this.BoneInfos.Count > 0) {
for (int boneId = 0; boneId < this.BoneInfos[animation.Name][frame].Length; boneId++) {
this._boneBuffer.SetValueDeferred(commandList, boneId, this.BoneInfos[animation.Name][frame][boneId].Transformation);
this._boneBuffer.SetValue(boneId, this.BoneInfos[animation.Name][frame][boneId].Transformation);
}

this._boneBuffer.UpdateBuffer(commandList);
}
}

/// <summary>
/// Resets the bone transformation matrices to their identity state and updates the buffer on the GPU using the provided command list.
/// </summary>
/// <param name="commandList">The command list used to record the buffer update command, ensuring the changes are applied to the GPU.</param>
public void ResetAnimationBones(CommandList commandList) {
for (int i = 0; i < 128; i++) {
this._boneBuffer.SetValue(i, Matrix4x4.Identity);
}

this._boneBuffer.UpdateBuffer(commandList);
}

/// <summary>
/// Renders the mesh using the specified command list, output description, transformation, and optional color.
Expand Down
19 changes: 16 additions & 3 deletions src/Bliss/CSharp/Geometry/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Assimp;
using Bliss.CSharp.Effects;
using Bliss.CSharp.Geometry.Animations;
using Bliss.CSharp.Geometry.Animations.Bones;
using Bliss.CSharp.Geometry.Conversions;
using Bliss.CSharp.Graphics.VertexTypes;
using Bliss.CSharp.Logging;
Expand All @@ -26,8 +25,6 @@
using Material = Bliss.CSharp.Materials.Material;
using AMaterial = Assimp.Material;
using Color = Bliss.CSharp.Colors.Color;
using Matrix4x4 = System.Numerics.Matrix4x4;
using Quaternion = System.Numerics.Quaternion;
using TextureType = Assimp.TextureType;

namespace Bliss.CSharp.Geometry;
Expand Down Expand Up @@ -75,6 +72,12 @@ public class Model : Disposable {
/// </summary>
public BoundingBox BoundingBox { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="Model"/> class with the specified graphics device, meshes, and animations.
/// </summary>
/// <param name="graphicsDevice">The <see cref="GraphicsDevice"/> used for rendering and resource management.</param>
/// <param name="meshes">An array of <see cref="Mesh"/> objects representing the geometric components of the model.</param>
/// <param name="animations">An array of <see cref="ModelAnimation"/> objects defining the animations for the model.</param>
public Model(GraphicsDevice graphicsDevice, Mesh[] meshes, ModelAnimation[] animations) {
this.GraphicsDevice = graphicsDevice;
this.Meshes = meshes;
Expand Down Expand Up @@ -330,6 +333,16 @@ public void UpdateAnimationBones(CommandList commandList, ModelAnimation animati
mesh.UpdateAnimationBones(commandList, animation, frame);
}
}

/// <summary>
/// Resets the animation bone transformations for all meshes in the model using the given command list.
/// </summary>
/// <param name="commandList">The command list used to execute the reset operation on the GPU.</param>
public void ResetAnimationBones(CommandList commandList) {
foreach (Mesh mesh in this.Meshes) {
mesh.ResetAnimationBones(commandList);
}
}

/// <summary>
/// Draws the model using the specified command list, output description, sampler type, transform, blend state, and color.
Expand Down

0 comments on commit 2a4a16a

Please sign in to comment.