Added SetNodeTransformation with ModelBoneNode
To get and set a series of bones based on their ID (cherry picked from commit e0a113483e910660e45c53e059502733ce1d6ad6)
This commit is contained in:
@@ -174,6 +174,14 @@ void AnimatedModel::GetNodeTransformation(const StringView& nodeName, Matrix& no
|
|||||||
GetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
|
GetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimatedModel::GetNodeTransformation(Array<ModelBoneNode>& modelBoneNodes, bool worldSpace) const
|
||||||
|
{
|
||||||
|
for (ModelBoneNode& item : modelBoneNodes)
|
||||||
|
{
|
||||||
|
GetNodeTransformation(item.NodeIndex, item.NodeMatrix, worldSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AnimatedModel::SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTransformation, bool worldSpace)
|
void AnimatedModel::SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTransformation, bool worldSpace)
|
||||||
{
|
{
|
||||||
if (GraphInstance.NodesPose.IsEmpty())
|
if (GraphInstance.NodesPose.IsEmpty())
|
||||||
@@ -191,6 +199,33 @@ void AnimatedModel::SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTra
|
|||||||
OnAnimationUpdated();
|
OnAnimationUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimatedModel::SetNodeTransformation(Array<ModelBoneNode>& modelBoneNodes, bool worldSpace)
|
||||||
|
{
|
||||||
|
if (GraphInstance.NodesPose.IsEmpty())
|
||||||
|
const_cast<AnimatedModel*>(this)->PreInitSkinningData(); // Ensure to have valid nodes pose to return
|
||||||
|
|
||||||
|
// Calculate it once, outside loop
|
||||||
|
Matrix invWorld;
|
||||||
|
if (worldSpace)
|
||||||
|
{
|
||||||
|
Matrix world;
|
||||||
|
GetLocalToWorldMatrix(world);
|
||||||
|
Matrix::Invert(world, invWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < modelBoneNodes.Count(); i++)
|
||||||
|
{
|
||||||
|
int nodeIndex = modelBoneNodes[i].NodeIndex;
|
||||||
|
CHECK(nodeIndex >= 0 && nodeIndex < GraphInstance.NodesPose.Count());
|
||||||
|
GraphInstance.NodesPose[nodeIndex] = modelBoneNodes[i].NodeMatrix;
|
||||||
|
if (worldSpace)
|
||||||
|
{
|
||||||
|
GraphInstance.NodesPose[nodeIndex] = GraphInstance.NodesPose[nodeIndex] * invWorld;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OnAnimationUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
void AnimatedModel::SetNodeTransformation(const StringView& nodeName, const Matrix& nodeTransformation, bool worldSpace)
|
void AnimatedModel::SetNodeTransformation(const StringView& nodeName, const Matrix& nodeTransformation, bool worldSpace)
|
||||||
{
|
{
|
||||||
SetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
|
SetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
|
||||||
@@ -809,8 +844,11 @@ void AnimatedModel::OnAnimationUpdated_Async()
|
|||||||
_skinningData.OnDataChanged(!PerBoneMotionBlur);
|
_skinningData.OnDataChanged(!PerBoneMotionBlur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UpdateWhenOffscreen)
|
||||||
|
{
|
||||||
UpdateBounds();
|
UpdateBounds();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AnimatedModel::OnAnimationUpdated_Sync()
|
void AnimatedModel::OnAnimationUpdated_Sync()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
#include "Engine/Renderer/DrawCall.h"
|
#include "Engine/Renderer/DrawCall.h"
|
||||||
#include "Engine/Core/Delegate.h"
|
#include "Engine/Core/Delegate.h"
|
||||||
|
|
||||||
|
API_STRUCT() struct ModelBoneNode
|
||||||
|
{
|
||||||
|
DECLARE_SCRIPTING_TYPE_MINIMAL(ModelBoneNode);
|
||||||
|
|
||||||
|
API_FIELD() uint32 NodeIndex;
|
||||||
|
API_FIELD() Matrix NodeMatrix;
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs an animation and renders a skinned model.
|
/// Performs an animation and renders a skinned model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -236,13 +244,21 @@ public:
|
|||||||
/// <param name="worldSpace">True if convert matrices into world-space, otherwise returned values will be in local-space of the actor.</param>
|
/// <param name="worldSpace">True if convert matrices into world-space, otherwise returned values will be in local-space of the actor.</param>
|
||||||
API_FUNCTION() void GetNodeTransformation(const StringView& nodeName, API_PARAM(Out) Matrix& nodeTransformation, bool worldSpace = false) const;
|
API_FUNCTION() void GetNodeTransformation(const StringView& nodeName, API_PARAM(Out) Matrix& nodeTransformation, bool worldSpace = false) const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the node final transformation for a series of nodes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modelBoneNodes">The series of nodes that will be returned</param>
|
||||||
|
/// <param name="worldSpace">True if convert matrices into world-space, otherwise returned values will be in local-space of the actor.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
API_FUNCTION() void GetNodeTransformation(API_PARAM(Out) Array<ModelBoneNode>& modelBoneNodes, bool worldSpace = false) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the node final transformation. If multiple nodes are to be set within a frame, do not use set worldSpace to true, and do the conversion yourself to avoid recalculation of inv matrices.
|
/// Sets the node final transformation. If multiple nodes are to be set within a frame, do not use set worldSpace to true, and do the conversion yourself to avoid recalculation of inv matrices.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodeIndex">The index of the skinned model skeleton node.</param>
|
/// <param name="nodeIndex">The index of the skinned model skeleton node.</param>
|
||||||
/// <param name="nodeTransformation">The final node transformation matrix.</param>
|
/// <param name="nodeTransformation">The final node transformation matrix.</param>
|
||||||
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
||||||
API_FUNCTION() void SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTransformation, bool worldSpace = false);
|
API_FUNCTION() void SetNodeTransformation(int32 nodeIndex, const Matrix& modelBoneNodes, bool worldSpace = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the node final transformation. If multiple nodes are to be set within a frame, do not use set worldSpace to true, and do the conversion yourself to avoid recalculation of inv matrices.
|
/// Sets the node final transformation. If multiple nodes are to be set within a frame, do not use set worldSpace to true, and do the conversion yourself to avoid recalculation of inv matrices.
|
||||||
@@ -252,6 +268,14 @@ public:
|
|||||||
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
||||||
API_FUNCTION() void SetNodeTransformation(const StringView& nodeName, const Matrix& nodeTransformation, bool worldSpace = false);
|
API_FUNCTION() void SetNodeTransformation(const StringView& nodeName, const Matrix& nodeTransformation, bool worldSpace = false);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a group of nodes final transformation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodesTransformations">Array of the final node transformation matrix.</param>
|
||||||
|
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
API_FUNCTION() void SetNodeTransformation(Array<ModelBoneNode>& nodesTransformations, bool worldSpace = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the closest node to a given location.
|
/// Finds the closest node to a given location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user