Add ShowDebugDrawSkeleton to preview Animated Model skeleton via Debug Draw
#2443
This commit is contained in:
@@ -336,7 +336,8 @@ namespace FlaxEditor.Viewport.Previews
|
|||||||
if (_showNodes)
|
if (_showNodes)
|
||||||
{
|
{
|
||||||
// Draw bounding box at the node locations
|
// Draw bounding box at the node locations
|
||||||
var localBox = new OrientedBoundingBox(new Vector3(-1.0f), new Vector3(1.0f));
|
var boxSize = Mathf.Min(1.0f, _previewModel.Sphere.Radius / 100.0f);
|
||||||
|
var localBox = new OrientedBoundingBox(new Vector3(-boxSize), new Vector3(boxSize));
|
||||||
for (int nodeIndex = 0; nodeIndex < pose.Length; nodeIndex++)
|
for (int nodeIndex = 0; nodeIndex < pose.Length; nodeIndex++)
|
||||||
{
|
{
|
||||||
if (nodesMask != null && !nodesMask[nodeIndex])
|
if (nodesMask != null && !nodesMask[nodeIndex])
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "Engine/Animations/Animations.h"
|
#include "Engine/Animations/Animations.h"
|
||||||
#include "Engine/Engine/Engine.h"
|
#include "Engine/Engine/Engine.h"
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
#include "Engine/Core/Math/OrientedBoundingBox.h"
|
||||||
|
#include "Engine/Core/Math/Matrix3x3.h"
|
||||||
#include "Editor/Editor.h"
|
#include "Editor/Editor.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Engine/Graphics/GPUContext.h"
|
#include "Engine/Graphics/GPUContext.h"
|
||||||
@@ -1018,6 +1020,45 @@ void AnimatedModel::OnDebugDrawSelected()
|
|||||||
ModelInstanceActor::OnDebugDrawSelected();
|
ModelInstanceActor::OnDebugDrawSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimatedModel::OnDebugDraw()
|
||||||
|
{
|
||||||
|
if (ShowDebugDrawSkeleton && SkinnedModel && AnimationGraph)
|
||||||
|
{
|
||||||
|
if (GraphInstance.NodesPose.IsEmpty())
|
||||||
|
PreInitSkinningData();
|
||||||
|
Matrix world;
|
||||||
|
GetLocalToWorldMatrix(world);
|
||||||
|
|
||||||
|
// Draw bounding box at the node locations
|
||||||
|
const float boxSize = Math::Min(1.0f, _sphere.Radius / 100.0f);
|
||||||
|
OrientedBoundingBox localBox(Vector3(-boxSize), Vector3(boxSize));
|
||||||
|
for (int32 nodeIndex = 0; nodeIndex < GraphInstance.NodesPose.Count(); nodeIndex++)
|
||||||
|
{
|
||||||
|
Matrix transform = GraphInstance.NodesPose[nodeIndex] * world;
|
||||||
|
Float3 scale, translation;
|
||||||
|
Matrix3x3 rotation;
|
||||||
|
transform.Decompose(scale, rotation, translation);
|
||||||
|
transform = Matrix::Invert(Matrix::Scaling(scale)) * transform;
|
||||||
|
OrientedBoundingBox box = localBox * transform;
|
||||||
|
DEBUG_DRAW_WIRE_BOX(box, Color::Green, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nodes connections
|
||||||
|
for (int32 nodeIndex = 0; nodeIndex < SkinnedModel->Skeleton.Nodes.Count(); nodeIndex++)
|
||||||
|
{
|
||||||
|
int32 parentIndex = SkinnedModel->Skeleton.Nodes[nodeIndex].ParentIndex;
|
||||||
|
if (parentIndex != -1)
|
||||||
|
{
|
||||||
|
Float3 parentPos = (GraphInstance.NodesPose[parentIndex] * world).GetTranslation();
|
||||||
|
Float3 bonePos = (GraphInstance.NodesPose[nodeIndex] * world).GetTranslation();
|
||||||
|
DEBUG_DRAW_LINE(parentPos, bonePos, Color::Green, 0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelInstanceActor::OnDebugDraw();
|
||||||
|
}
|
||||||
|
|
||||||
BoundingBox AnimatedModel::GetEditorBox() const
|
BoundingBox AnimatedModel::GetEditorBox() const
|
||||||
{
|
{
|
||||||
if (SkinnedModel)
|
if (SkinnedModel)
|
||||||
|
|||||||
@@ -168,6 +168,13 @@ public:
|
|||||||
API_FIELD(Attributes="EditorOrder(120), DefaultValue(null), EditorDisplay(\"Skinned Model\")")
|
API_FIELD(Attributes="EditorOrder(120), DefaultValue(null), EditorDisplay(\"Skinned Model\")")
|
||||||
ScriptingObjectReference<Actor> RootMotionTarget;
|
ScriptingObjectReference<Actor> RootMotionTarget;
|
||||||
|
|
||||||
|
#if USE_EDITOR
|
||||||
|
/// <summary>
|
||||||
|
/// If checked, the skeleton pose will be shawn during debug shapes drawing.
|
||||||
|
/// </summary>
|
||||||
|
API_FIELD(Attributes="EditorOrder(200), EditorDisplay(\"Skinned Model\")") bool ShowDebugDrawSkeleton = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The graph instance data container. For dynamic usage only at runtime, not serialized.
|
/// The graph instance data container. For dynamic usage only at runtime, not serialized.
|
||||||
@@ -416,6 +423,7 @@ public:
|
|||||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
void OnDebugDrawSelected() override;
|
void OnDebugDrawSelected() override;
|
||||||
|
void OnDebugDraw() override;
|
||||||
BoundingBox GetEditorBox() const override;
|
BoundingBox GetEditorBox() const override;
|
||||||
#endif
|
#endif
|
||||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user