render solid skeleton option (#5610)
* render solid skeleton option Signed-off-by: rhhong <rhhong@amazon.com> * Fix broken build Signed-off-by: rhhong <rhhong@amazon.com> * CR update Signed-off-by: rhhong <rhhong@amazon.com>
This commit is contained in:
@@ -49,8 +49,14 @@ namespace AZ::Render
|
|||||||
RenderAABB(instance, renderActorSettings.m_staticAABBColor);
|
RenderAABB(instance, renderActorSettings.m_staticAABBColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render skeleton
|
// Render simple line skeleton
|
||||||
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_LINESKELETON])
|
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_LINESKELETON])
|
||||||
|
{
|
||||||
|
RenderLineSkeleton(instance, renderActorSettings.m_lineSkeletonColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render advance skeleton
|
||||||
|
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_SKELETON])
|
||||||
{
|
{
|
||||||
RenderSkeleton(instance, renderActorSettings.m_skeletonColor);
|
RenderSkeleton(instance, renderActorSettings.m_skeletonColor);
|
||||||
}
|
}
|
||||||
@@ -110,6 +116,29 @@ namespace AZ::Render
|
|||||||
return aabbRadius * 0.01f;
|
return aabbRadius * 0.01f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AtomActorDebugDraw::CalculateBoneScale(EMotionFX::ActorInstance* actorInstance, EMotionFX::Node* node)
|
||||||
|
{
|
||||||
|
// Get the transform data
|
||||||
|
EMotionFX::TransformData* transformData = actorInstance->GetTransformData();
|
||||||
|
const EMotionFX::Pose* pose = transformData->GetCurrentPose();
|
||||||
|
|
||||||
|
const size_t nodeIndex = node->GetNodeIndex();
|
||||||
|
const size_t parentIndex = node->GetParentIndex();
|
||||||
|
const AZ::Vector3 nodeWorldPos = pose->GetWorldSpaceTransform(nodeIndex).m_position;
|
||||||
|
|
||||||
|
if (parentIndex != InvalidIndex)
|
||||||
|
{
|
||||||
|
const AZ::Vector3 parentWorldPos = pose->GetWorldSpaceTransform(parentIndex).m_position;
|
||||||
|
const AZ::Vector3 bone = parentWorldPos - nodeWorldPos;
|
||||||
|
const float boneLength = bone.GetLengthEstimate();
|
||||||
|
|
||||||
|
// 10% of the bone length is the sphere size
|
||||||
|
return boneLength * 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void AtomActorDebugDraw::PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM)
|
void AtomActorDebugDraw::PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM)
|
||||||
{
|
{
|
||||||
// Check if we have already prepared for the given mesh
|
// Check if we have already prepared for the given mesh
|
||||||
@@ -145,7 +174,7 @@ namespace AZ::Render
|
|||||||
auxGeom->DrawAabb(aabb, aabbColor, RPI::AuxGeomDraw::DrawStyle::Line);
|
auxGeom->DrawAabb(aabb, aabbColor, RPI::AuxGeomDraw::DrawStyle::Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomActorDebugDraw::RenderSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor)
|
void AtomActorDebugDraw::RenderLineSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor)
|
||||||
{
|
{
|
||||||
RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue();
|
RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue();
|
||||||
|
|
||||||
@@ -189,6 +218,42 @@ namespace AZ::Render
|
|||||||
auxGeom->DrawLines(lineArgs);
|
auxGeom->DrawLines(lineArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomActorDebugDraw::RenderSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor)
|
||||||
|
{
|
||||||
|
RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue();
|
||||||
|
|
||||||
|
const EMotionFX::TransformData* transformData = instance->GetTransformData();
|
||||||
|
const EMotionFX::Skeleton* skeleton = instance->GetActor()->GetSkeleton();
|
||||||
|
const EMotionFX::Pose* pose = transformData->GetCurrentPose();
|
||||||
|
const size_t numEnabled = instance->GetNumEnabledNodes();
|
||||||
|
for (size_t i = 0; i < numEnabled; ++i)
|
||||||
|
{
|
||||||
|
EMotionFX::Node* joint = skeleton->GetNode(instance->GetEnabledNode(i));
|
||||||
|
const size_t jointIndex = joint->GetNodeIndex();
|
||||||
|
const size_t parentIndex = joint->GetParentIndex();
|
||||||
|
|
||||||
|
// check if this node has a parent and is a bone, if not skip it
|
||||||
|
if (parentIndex == InvalidIndex)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AZ::Vector3 nodeWorldPos = pose->GetWorldSpaceTransform(jointIndex).m_position;
|
||||||
|
const AZ::Vector3 parentWorldPos = pose->GetWorldSpaceTransform(parentIndex).m_position;
|
||||||
|
const AZ::Vector3 bone = parentWorldPos - nodeWorldPos;
|
||||||
|
const AZ::Vector3 boneDirection = bone.GetNormalizedEstimate();
|
||||||
|
const AZ::Vector3 centerWorldPos = bone / 2 + nodeWorldPos;
|
||||||
|
const float boneLength = bone.GetLengthEstimate();
|
||||||
|
const float boneScale = CalculateBoneScale(instance, joint);
|
||||||
|
const float parentBoneScale = CalculateBoneScale(instance, skeleton->GetNode(parentIndex));
|
||||||
|
const float cylinderSize = boneLength - boneScale - parentBoneScale;
|
||||||
|
|
||||||
|
// Render the bone cylinder, the cylinder will be directed towards the node's parent and must fit between the spheres
|
||||||
|
auxGeom->DrawCylinder(centerWorldPos, boneDirection, boneScale, cylinderSize, skeletonColor);
|
||||||
|
auxGeom->DrawSphere(nodeWorldPos, boneScale, skeletonColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AtomActorDebugDraw::RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance)
|
void AtomActorDebugDraw::RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance)
|
||||||
{
|
{
|
||||||
RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue();
|
RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue();
|
||||||
|
|||||||
@@ -37,9 +37,12 @@ namespace AZ::Render
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
float CalculateBoneScale(EMotionFX::ActorInstance* actorInstance, EMotionFX::Node* node);
|
||||||
float CalculateScaleMultiplier(EMotionFX::ActorInstance* instance) const;
|
float CalculateScaleMultiplier(EMotionFX::ActorInstance* instance) const;
|
||||||
void PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM);
|
void PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM);
|
||||||
|
|
||||||
void RenderAABB(EMotionFX::ActorInstance* instance, const AZ::Color& aabbColor);
|
void RenderAABB(EMotionFX::ActorInstance* instance, const AZ::Color& aabbColor);
|
||||||
|
void RenderLineSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor);
|
||||||
void RenderSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor);
|
void RenderSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor);
|
||||||
void RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance);
|
void RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance);
|
||||||
void RenderNormals(
|
void RenderNormals(
|
||||||
|
|||||||
+2
@@ -545,6 +545,7 @@ namespace EMStudio
|
|||||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &RenderOptions::OnLineSkeletonColorChangedCallback)
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, &RenderOptions::OnLineSkeletonColorChangedCallback)
|
||||||
->DataElement(AZ::Edit::UIHandlers::Default, &RenderOptions::m_skeletonColor, "Solid skeleton color",
|
->DataElement(AZ::Edit::UIHandlers::Default, &RenderOptions::m_skeletonColor, "Solid skeleton color",
|
||||||
"Solid skeleton color.")
|
"Solid skeleton color.")
|
||||||
|
->Attribute(AZ_CRC("AlphaChannel", 0xa0cab5cf), true)
|
||||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &RenderOptions::OnSkeletonColorChangedCallback)
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, &RenderOptions::OnSkeletonColorChangedCallback)
|
||||||
->DataElement(AZ::Edit::UIHandlers::Default, &RenderOptions::m_selectionColor, "Selection gizmo color",
|
->DataElement(AZ::Edit::UIHandlers::Default, &RenderOptions::m_selectionColor, "Selection gizmo color",
|
||||||
"Selection gizmo color")
|
"Selection gizmo color")
|
||||||
@@ -1268,6 +1269,7 @@ namespace EMStudio
|
|||||||
void RenderOptions::OnSkeletonColorChangedCallback() const
|
void RenderOptions::OnSkeletonColorChangedCallback() const
|
||||||
{
|
{
|
||||||
PluginOptionsNotificationsBus::Event(s_skeletonColorOptionName, &PluginOptionsNotificationsBus::Events::OnOptionChanged, s_skeletonColorOptionName);
|
PluginOptionsNotificationsBus::Event(s_skeletonColorOptionName, &PluginOptionsNotificationsBus::Events::OnOptionChanged, s_skeletonColorOptionName);
|
||||||
|
CopyToRenderActorSettings(EMotionFX::GetRenderActorSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderOptions::OnSelectionColorChangedCallback() const
|
void RenderOptions::OnSelectionColorChangedCallback() const
|
||||||
|
|||||||
Reference in New Issue
Block a user