Change actorRenderFlag to use AZ ENUM CLASS instead of azstd::bitset (#7542)

* Fixes the problem with using actor render flags in actor component

Signed-off-by: rhhong <rhhong@amazon.com>

* In progress work for actor render flag rework

Signed-off-by: rhhong <rhhong@amazon.com>

* add an utlity function to check bit

Signed-off-by: rhhong <rhhong@amazon.com>

* code cleanup

Signed-off-by: rhhong <rhhong@amazon.com>

* More CR cleanup

Signed-off-by: rhhong <rhhong@amazon.com>

* build fix

Signed-off-by: rhhong <rhhong@amazon.com>

* CR feedback

Signed-off-by: rhhong <rhhong@amazon.com>
monroegm-disable-blank-issue-2
Roman 4 years ago committed by GitHub
parent 60d7533301
commit da421b7056
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -33,7 +33,7 @@ namespace AZ::Render
m_auxGeomFeatureProcessor = RPI::Scene::GetFeatureProcessorForEntity<RPI::AuxGeomFeatureProcessorInterface>(entityId);
}
void AtomActorDebugDraw::DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags, EMotionFX::ActorInstance* instance)
void AtomActorDebugDraw::DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags, EMotionFX::ActorInstance* instance)
{
if (!m_auxGeomFeatureProcessor || !instance)
{
@ -46,10 +46,12 @@ namespace AZ::Render
return;
}
using AZ::RHI::CheckBitsAny;
// Update the mesh deformers (perform cpu skinning and morphing) when needed.
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB] || renderFlags[EMotionFX::ActorRenderFlag::RENDER_FACENORMALS] ||
renderFlags[EMotionFX::ActorRenderFlag::RENDER_TANGENTS] || renderFlags[EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS] ||
renderFlags[EMotionFX::ActorRenderFlag::RENDER_WIREFRAME])
if (CheckBitsAny(renderFlags,
EMotionFX::ActorRenderFlags::AABB | EMotionFX::ActorRenderFlags::FaceNormals | EMotionFX::ActorRenderFlags::Tangents |
EMotionFX::ActorRenderFlags::VertexNormals | EMotionFX::ActorRenderFlags::Wireframe))
{
instance->UpdateMeshDeformers(0.0f, true);
}
@ -61,7 +63,7 @@ namespace AZ::Render
const float scaleMultiplier = CalculateScaleMultiplier(instance);
// Render aabb
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB])
if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::AABB))
{
RenderAABB(instance,
renderActorSettings.m_enabledNodeBasedAabb, renderActorSettings.m_nodeAABBColor,
@ -70,39 +72,39 @@ namespace AZ::Render
}
// Render simple line skeleton
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_LINESKELETON])
if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::LineSkeleton))
{
RenderLineSkeleton(instance, renderActorSettings.m_lineSkeletonColor);
}
// Render advanced skeleton
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_SKELETON])
if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::Skeleton))
{
RenderSkeleton(instance, renderActorSettings.m_skeletonColor);
}
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_NODENAMES])
if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::NodeNames))
{
RenderJointNames(instance, viewport, renderActorSettings.m_jointNameColor);
}
// Render internal EMFX debug lines.
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_EMFX_DEBUG])
if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::EmfxDebug))
{
RenderEMFXDebugDraw(instance);
}
// Render
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_NODEORIENTATION])
if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::NodeOrientation))
{
RenderNodeOrientations(instance, debugDisplay, renderActorSettings.m_nodeOrientationScale * scaleMultiplier);
}
// Render vertex normal, face normal, tagent and wireframe.
const bool renderVertexNormals = renderFlags[EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS];
const bool renderFaceNormals = renderFlags[EMotionFX::ActorRenderFlag::RENDER_FACENORMALS];
const bool renderTangents = renderFlags[EMotionFX::ActorRenderFlag::RENDER_TANGENTS];
const bool renderWireframe = renderFlags[EMotionFX::ActorRenderFlag::RENDER_WIREFRAME];
const bool renderVertexNormals = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::VertexNormals);
const bool renderFaceNormals = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::FaceNormals);
const bool renderTangents = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::Tangents);
const bool renderWireframe = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::Wireframe);
if (renderVertexNormals || renderFaceNormals || renderTangents || renderWireframe)
{

@ -40,7 +40,7 @@ namespace AZ::Render
public:
AtomActorDebugDraw(AZ::EntityId entityId);
void DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags, EMotionFX::ActorInstance* instance);
void DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags, EMotionFX::ActorInstance* instance);
private:

@ -79,7 +79,7 @@ namespace AZ::Render
UpdateBounds();
}
void AtomActorInstance::DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags)
void AtomActorInstance::DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags)
{
m_atomActorDebugDraw->DebugDraw(renderFlags, m_actorInstance);
}

@ -86,7 +86,7 @@ namespace AZ
// RenderActorInstance overrides ...
void OnTick(float timeDelta) override;
void DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags);
void DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags);
void UpdateBounds() override;
void SetMaterials(const EMotionFX::Integration::ActorAsset::MaterialList& materialPerLOD) override { AZ_UNUSED(materialPerLOD); };
void SetSkinningMethod(EMotionFX::Integration::SkinningMethod emfxSkinningMethod) override;

@ -191,7 +191,7 @@ namespace EMStudio
return result;
}
void AnimViewportRenderer::UpdateActorRenderFlag(EMotionFX::ActorRenderFlagBitset renderFlags)
void AnimViewportRenderer::UpdateActorRenderFlag(EMotionFX::ActorRenderFlags renderFlags)
{
for (AZ::Entity* entity : m_actorEntities)
{

@ -54,7 +54,7 @@ namespace EMStudio
//! Return the center position of the existing objects.
AZ::Vector3 GetCharacterCenter() const;
void UpdateActorRenderFlag(EMotionFX::ActorRenderFlagBitset renderFlags);
void UpdateActorRenderFlag(EMotionFX::ActorRenderFlags renderFlags);
AZStd::shared_ptr<AzFramework::Scene> GetFrameworkScene() const;
AZ::EntityId GetEntityId() const;
AzFramework::EntityContextId GetEntityContextId() const;

@ -26,7 +26,7 @@ namespace EMStudio
virtual void UpdateCameraFollowUp(bool followUp) = 0;
//! Update render flags
virtual void UpdateRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags) = 0;
virtual void UpdateRenderFlags(EMotionFX::ActorRenderFlags renderFlags) = 0;
};
using AnimViewportRequestBus = AZ::EBus<AnimViewportRequests>;

@ -61,35 +61,35 @@ namespace EMStudio
renderOptionsButton->setIcon(QIcon(":/EMotionFXAtom/Visualization.svg"));
addWidget(renderOptionsButton);
CreateViewOptionEntry(contextMenu, "Solid", EMotionFX::ActorRenderFlag::RENDER_SOLID);
CreateViewOptionEntry(contextMenu, "Wireframe", EMotionFX::ActorRenderFlag::RENDER_WIREFRAME);
CreateViewOptionEntry(contextMenu, "Solid", EMotionFX::ActorRenderFlagIndex::SOLID);
CreateViewOptionEntry(contextMenu, "Wireframe", EMotionFX::ActorRenderFlagIndex::WIREFRAME);
// [EMFX-TODO] Add those option once implemented.
// CreateViewOptionEntry(contextMenu, "Lighting", EMotionFX::ActorRenderFlag::RENDER_LIGHTING);
// CreateViewOptionEntry(contextMenu, "Backface Culling", EMotionFX::ActorRenderFlag::RENDER_BACKFACECULLING);
// CreateViewOptionEntry(contextMenu, "Lighting", EMotionFX::ActorRenderFlagIndex::RENDER_LIGHTING);
// CreateViewOptionEntry(contextMenu, "Backface Culling", EMotionFX::ActorRenderFlagIndex::RENDER_BACKFACECULLING);
contextMenu->addSeparator();
CreateViewOptionEntry(contextMenu, "Vertex Normals", EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS);
CreateViewOptionEntry(contextMenu, "Face Normals", EMotionFX::ActorRenderFlag::RENDER_FACENORMALS);
CreateViewOptionEntry(contextMenu, "Tangents", EMotionFX::ActorRenderFlag::RENDER_TANGENTS);
CreateViewOptionEntry(contextMenu, "Actor Bounding Boxes", EMotionFX::ActorRenderFlag::RENDER_AABB);
CreateViewOptionEntry(contextMenu, "Vertex Normals", EMotionFX::ActorRenderFlagIndex::VERTEXNORMALS);
CreateViewOptionEntry(contextMenu, "Face Normals", EMotionFX::ActorRenderFlagIndex::FACENORMALS);
CreateViewOptionEntry(contextMenu, "Tangents", EMotionFX::ActorRenderFlagIndex::TANGENTS);
CreateViewOptionEntry(contextMenu, "Actor Bounding Boxes", EMotionFX::ActorRenderFlagIndex::AABB);
contextMenu->addSeparator();
CreateViewOptionEntry(contextMenu, "Line Skeleton", EMotionFX::ActorRenderFlag::RENDER_LINESKELETON);
CreateViewOptionEntry(contextMenu, "Solid Skeleton", EMotionFX::ActorRenderFlag::RENDER_SKELETON);
CreateViewOptionEntry(contextMenu, "Joint Names", EMotionFX::ActorRenderFlag::RENDER_NODENAMES);
CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlag::RENDER_NODEORIENTATION);
CreateViewOptionEntry(contextMenu, "Line Skeleton", EMotionFX::ActorRenderFlagIndex::LINESKELETON);
CreateViewOptionEntry(contextMenu, "Solid Skeleton", EMotionFX::ActorRenderFlagIndex::SKELETON);
CreateViewOptionEntry(contextMenu, "Joint Names", EMotionFX::ActorRenderFlagIndex::NODENAMES);
CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlagIndex::NODEORIENTATION);
// [EMFX-TODO] Add those option once implemented.
// CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlag::RENDER_ACTORBINDPOSE);
// CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlagIndex::RENDER_ACTORBINDPOSE);
contextMenu->addSeparator();
CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlag::RENDER_HITDETECTION_COLLIDERS, true,
CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlagIndex::HITDETECTION_COLLIDERS, true,
":/EMotionFXAtom/HitDetection.svg");
CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlag::RENDER_RAGDOLL_COLLIDERS, true,
CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlagIndex::RAGDOLL_COLLIDERS, true,
":/EMotionFXAtom/RagdollCollider.svg");
CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlag::RENDER_RAGDOLL_JOINTLIMITS, true,
CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlagIndex::RAGDOLL_JOINTLIMITS, true,
":/EMotionFXAtom/RagdollJointLimit.svg");
CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlag::RENDER_CLOTH_COLLIDERS, true,
CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlagIndex::CLOTH_COLLIDERS, true,
":/EMotionFXAtom/Cloth.svg");
CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlag::RENDER_SIMULATEDOBJECT_COLLIDERS, true,
CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlagIndex::SIMULATEDOBJECT_COLLIDERS, true,
":/EMotionFXAtom/SimulatedObjectCollider.svg");
CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlag::RENDER_SIMULATEJOINTS);
CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlagIndex::SIMULATEJOINTS);
}
// Add the camera button
@ -158,7 +158,7 @@ namespace EMStudio
}
void AnimViewportToolBar::CreateViewOptionEntry(
QMenu* menu, const char* menuEntryName, uint32_t actionIndex, bool visible, const char* iconFileName)
QMenu* menu, const char* menuEntryName, AZ::u8 actionIndex, bool visible, const char* iconFileName)
{
QAction* action = menu->addAction(
menuEntryName,
@ -194,13 +194,13 @@ namespace EMStudio
m_manipulatorActions[mode]->setChecked(true);
}
const EMotionFX::ActorRenderFlagBitset renderFlags = renderOptions->GetRenderFlags();
for (size_t i = 0; i < renderFlags.size(); ++i)
const EMotionFX::ActorRenderFlags renderFlags = renderOptions->GetRenderFlags();
for (uint8 i = 0; i < EMotionFX::ActorRenderFlagIndex::NUM_RENDERFLAGINDEXES; ++i)
{
QAction* action = m_renderActions[i];
if (action)
{
action->setChecked(renderFlags[i]);
action->setChecked(EMotionFX::ActorRenderFlagUtil::CheckBit(renderFlags, i));
}
}
}

@ -30,11 +30,11 @@ namespace EMStudio
private:
void CreateViewOptionEntry(
QMenu* menu, const char* menuEntryName, uint32_t actionIndex, bool visible = true, const char* iconFileName = nullptr);
QMenu* menu, const char* menuEntryName, AZ::u8 actionIndex, bool visible = true, const char* iconFileName = nullptr);
AtomRenderPlugin* m_plugin = nullptr;
QAction* m_manipulatorActions[RenderOptions::ManipulatorMode::NUM_MODES] = { nullptr };
QAction* m_renderActions[EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS] = { nullptr };
QAction* m_renderActions[EMotionFX::ActorRenderFlagIndex::NUM_RENDERFLAGINDEXES] = { nullptr };
QAction* m_followCharacterAction = nullptr;
};
}

@ -229,7 +229,7 @@ namespace EMStudio
}
}
void AnimViewportWidget::UpdateRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags)
void AnimViewportWidget::UpdateRenderFlags(EMotionFX::ActorRenderFlags renderFlags)
{
m_renderer->UpdateActorRenderFlag(renderFlags);
}

@ -45,7 +45,7 @@ namespace EMStudio
// AnimViewportRequestBus::Handler overrides
void UpdateCameraViewMode(RenderOptions::CameraViewMode mode);
void UpdateCameraFollowUp(bool follow);
void UpdateRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags);
void UpdateRenderFlags(EMotionFX::ActorRenderFlags renderFlags);
// ViewportPluginRequestBus::Handler overrides
AZ::s32 GetViewportId() const;

@ -300,7 +300,7 @@ namespace EMStudio
return &m_renderOptions;
}
void AtomRenderPlugin::Render([[maybe_unused]]EMotionFX::ActorRenderFlagBitset renderFlags)
void AtomRenderPlugin::Render([[maybe_unused]]EMotionFX::ActorRenderFlags renderFlags)
{
if (!m_animViewportWidget)
{

@ -61,7 +61,7 @@ namespace EMStudio
void SaveRenderOptions();
RenderOptions* GetRenderOptions();
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
void Render(EMotionFX::ActorRenderFlags renderFlags) override;
void SetManipulatorMode(RenderOptions::ManipulatorMode mode);
private:

@ -96,7 +96,7 @@ namespace EMStudio
virtual void LegacyRender(RenderPlugin* renderPlugin, RenderInfo* renderInfo) { MCORE_UNUSED(renderPlugin); MCORE_UNUSED(renderInfo); }
//! Render function will call atom auxGeom internally to render. This is the replacement for LegacyRender function.
virtual void Render(EMotionFX::ActorRenderFlagBitset renderFlags)
virtual void Render(EMotionFX::ActorRenderFlags renderFlags)
{
AZ_UNUSED(renderFlags);
};

@ -255,12 +255,7 @@ namespace EMStudio
settings->setValue("cameraFollowUp", m_cameraFollowUp);
// Save render flags
settings->beginGroup("renderFlags");
for (uint32 i = 0; i < EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS; ++i)
{
settings->setValue(QString(i), (bool)m_renderFlags[i]);
}
settings->endGroup();
settings->setValue("renderFlags", static_cast<AZ::u32>(m_renderFlags));
}
RenderOptions RenderOptions::Load(QSettings* settings)
@ -333,14 +328,8 @@ namespace EMStudio
options.m_cameraFollowUp = settings->value("CameraFollowUp", options.m_cameraFollowUp).toBool();
// Read render flags
settings->beginGroup("renderFlags");
for (uint32 i = 0; i < EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS; ++i)
{
const bool defaultValue = (i == EMotionFX::ActorRenderFlag::RENDER_SOLID);
const bool isEnabled = settings->value(QString(i), defaultValue).toBool();
options.m_renderFlags[i] = isEnabled;
}
settings->endGroup();
options.m_renderFlags =
EMotionFX::ActorRenderFlags(settings->value("RenderFlags", static_cast<int>(EMotionFX::ActorRenderFlags::Default)).toInt());
options.CopyToRenderActorSettings(EMotionFX::GetRenderActorSettings());
@ -1104,17 +1093,17 @@ namespace EMStudio
return m_cameraFollowUp;
}
void RenderOptions::ToggerRenderFlag(int index)
void RenderOptions::ToggerRenderFlag(uint8 index)
{
m_renderFlags[index] = !m_renderFlags[index];
m_renderFlags ^= EMotionFX::ActorRenderFlags(AZ_BIT(index));
}
void RenderOptions::SetRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags)
void RenderOptions::SetRenderFlags(EMotionFX::ActorRenderFlags renderFlags)
{
m_renderFlags = renderFlags;
}
EMotionFX::ActorRenderFlagBitset RenderOptions::GetRenderFlags() const
EMotionFX::ActorRenderFlags RenderOptions::GetRenderFlags() const
{
return m_renderFlags;
}

@ -284,9 +284,9 @@ namespace EMStudio
void SetCameraFollowUp(bool followUp);
bool GetCameraFollowUp() const;
void ToggerRenderFlag(int index);
void SetRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags);
EMotionFX::ActorRenderFlagBitset GetRenderFlags() const;
void ToggerRenderFlag(uint8 index);
void SetRenderFlags(EMotionFX::ActorRenderFlags renderFlags);
EMotionFX::ActorRenderFlags GetRenderFlags() const;
private:
void OnGridUnitSizeChangedCallback() const;
@ -406,7 +406,7 @@ namespace EMStudio
ManipulatorMode m_manipulatorMode = ManipulatorMode::SELECT;
CameraViewMode m_cameraViewMode = CameraViewMode::DEFAULT;
bool m_cameraFollowUp = false;
EMotionFX::ActorRenderFlagBitset m_renderFlags;
EMotionFX::ActorRenderFlags m_renderFlags;
};
} // namespace EMStudio

@ -196,10 +196,9 @@ namespace EMotionFX
renderInfo);
}
void ClothJointInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
void ClothJointInspectorPlugin::Render(EMotionFX::ActorRenderFlags renderFlags)
{
const bool renderColliders = renderFlags[RENDER_CLOTH_COLLIDERS];
if (!renderColliders)
if (!AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::ClothColliders))
{
return;
}

@ -48,7 +48,7 @@ namespace EMotionFX
void OnContextMenu(QMenu* menu, const QModelIndexList& selectedRowIndices) override;
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
void Render(EMotionFX::ActorRenderFlags renderFlags) override;
static bool IsJointInCloth(const QModelIndex& index);
public slots:

@ -181,10 +181,9 @@ namespace EMotionFX
renderInfo);
}
void HitDetectionJointInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
void HitDetectionJointInspectorPlugin::Render(EMotionFX::ActorRenderFlags renderFlags)
{
const bool renderColliders = renderFlags[EMotionFX::ActorRenderFlag::RENDER_HITDETECTION_COLLIDERS];
if (!renderColliders)
if (!AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::HitDetectionColliders))
{
return;
}

@ -44,7 +44,7 @@ namespace EMotionFX
void OnContextMenu(QMenu* menu, const QModelIndexList& selectedRowIndices) override;
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
void Render(EMotionFX::ActorRenderFlags renderFlags) override;
public slots:
void OnAddCollider();

@ -595,10 +595,10 @@ namespace EMotionFX
renderInfo->m_renderUtil->RenderArrow(0.1f, jointChildWorldSpaceTransformNoScale.m_position, MCore::GetRight(jointChildWorldSpaceTransformNoScale.ToAZTransform()), color);
}
void RagdollNodeInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
void RagdollNodeInspectorPlugin::Render(EMotionFX::ActorRenderFlags renderFlags)
{
const bool renderColliders = renderFlags[RENDER_RAGDOLL_COLLIDERS];
const bool renderJointLimits = renderFlags[RENDER_RAGDOLL_JOINTLIMITS];
const bool renderColliders = AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::RagdollColliders);
const bool renderJointLimits = AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::RagdollJointLimits);
if (!renderColliders && !renderJointLimits)
{
return;

@ -74,7 +74,7 @@ namespace EMotionFX
const MCore::RGBAColor& color);
//! Those function replaces legacyRender function and calls atom auxGeom render internally.
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
void Render(EMotionFX::ActorRenderFlags renderFlags) override;
void RenderRagdoll(
ActorInstance* actorInstance,
bool renderColliders,

@ -570,7 +570,7 @@ namespace EMotionFX
drawData->Unlock();
}
void SimulatedObjectWidget::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
void SimulatedObjectWidget::Render(EMotionFX::ActorRenderFlags renderFlags)
{
if (!m_actor || !m_actorInstance)
{
@ -578,9 +578,8 @@ namespace EMotionFX
}
const AZ::Render::RenderActorSettings& settings = EMotionFX::GetRenderActorSettings();
const bool renderSimulatedJoints = renderFlags[RENDER_SIMULATEJOINTS];
const AZStd::unordered_set<size_t>& selectedJointIndices = EMStudio::GetManager()->GetSelectedJointIndices();
if (renderSimulatedJoints && !selectedJointIndices.empty())
if (AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::SimulatedJoints) && !selectedJointIndices.empty())
{
// Render the joint radius.
const size_t actorInstanceCount = GetActorManager().GetNumActorInstances();
@ -613,8 +612,7 @@ namespace EMotionFX
}
}
const bool renderColliders = renderFlags[RENDER_SIMULATEDOBJECT_COLLIDERS];
if (renderColliders)
if (AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::SimulatedObjectColliders))
{
ColliderContainerWidget::RenderColliders(PhysicsSetup::SimulatedObjectCollider,
settings.m_simulatedObjectColliderColor, settings.m_selectedSimulatedObjectColliderColor);

@ -61,7 +61,7 @@ namespace EMotionFX
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
void LegacyRenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color);
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
void Render(EMotionFX::ActorRenderFlags renderFlags) override;
void RenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color);
SimulatedObjectModel* GetSimulatedObjectModel() const;

@ -12,6 +12,7 @@
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Preprocessor/EnumReflectUtils.h>
#include <AzFramework/Physics/Ragdoll.h>
#include <AzFramework/Physics/RagdollPhysicsBus.h>
@ -131,7 +132,10 @@ namespace EMotionFX
return AZ::Edit::PropertyVisibility::Show;
}
//////////////////////////////////////////////////////////////////////////
AZ_ENUM_DEFINE_REFLECT_UTILITIES(ActorRenderFlags);
void ActorComponent::Configuration::Reflect(AZ::ReflectContext* context)
{
BoundingBoxConfiguration::Reflect(context);
@ -139,19 +143,19 @@ namespace EMotionFX
auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
ActorRenderFlagsReflect(*serializeContext);
serializeContext->Class<Configuration>()
->Version(4)
->Version(5)
->Field("ActorAsset", &Configuration::m_actorAsset)
->Field("MaterialPerLOD", &Configuration::m_materialPerLOD)
->Field("RenderSkeleton", &Configuration::m_renderSkeleton)
->Field("RenderCharacter", &Configuration::m_renderCharacter)
->Field("RenderBounds", &Configuration::m_renderBounds)
->Field("AttachmentType", &Configuration::m_attachmentType)
->Field("AttachmentTarget", &Configuration::m_attachmentTarget)
->Field("SkinningMethod", &Configuration::m_skinningMethod)
->Field("LODLevel", &Configuration::m_lodLevel)
->Field("BoundingBoxConfig", &Configuration::m_bboxConfig)
->Field("ForceJointsUpdateOOV", &Configuration::m_forceUpdateJointsOOV)
->Field("RenderFlags", &Configuration::m_renderFlags)
;
}
}
@ -250,8 +254,6 @@ namespace EMotionFX
{
m_configuration = *configuration;
}
m_debugRenderFlags[RENDER_SOLID] = true;
}
//////////////////////////////////////////////////////////////////////////
@ -344,20 +346,24 @@ namespace EMotionFX
//////////////////////////////////////////////////////////////////////////
bool ActorComponent::GetRenderCharacter() const
{
return m_configuration.m_renderCharacter;
return AZ::RHI::CheckBitsAny(m_configuration.m_renderFlags, ActorRenderFlags::Solid);
}
//////////////////////////////////////////////////////////////////////////
void ActorComponent::SetRenderCharacter(bool enable)
{
if (m_configuration.m_renderCharacter != enable)
if (enable)
{
m_configuration.m_renderFlags |= ActorRenderFlags::Solid;
}
else
{
m_configuration.m_renderCharacter = enable;
m_configuration.m_renderFlags &= ~ActorRenderFlags::Solid;
}
if (m_renderActorInstance)
{
m_renderActorInstance->SetIsVisible(m_configuration.m_renderCharacter);
}
if (m_renderActorInstance)
{
m_renderActorInstance->SetIsVisible(enable);
}
}
@ -394,9 +400,9 @@ namespace EMotionFX
return m_sceneFinishSimHandler.IsConnected();
}
void ActorComponent::SetRenderFlag(ActorRenderFlagBitset renderFlags)
void ActorComponent::SetRenderFlag(ActorRenderFlags renderFlags)
{
m_debugRenderFlags = renderFlags;
m_configuration.m_renderFlags = renderFlags;
}
void ActorComponent::CheckActorCreation()
@ -456,7 +462,7 @@ namespace EMotionFX
if (m_renderActorInstance)
{
m_renderActorInstance->SetIsVisible(m_configuration.m_renderCharacter);
m_renderActorInstance->SetIsVisible(AZ::RHI::CheckBitsAny(m_configuration.m_renderFlags, ActorRenderFlags::Solid));
}
}
@ -563,22 +569,18 @@ namespace EMotionFX
m_renderActorInstance->OnTick(deltaTime);
m_renderActorInstance->UpdateBounds();
AZ::Interface<AzFramework::IEntityBoundsUnion>::Get()->RefreshEntityLocalBoundsUnion(GetEntityId());
const bool renderActorSolid = AZ::RHI::CheckBitsAny(m_configuration.m_renderFlags, ActorRenderFlags::Solid);
// Optimization: Set the actor instance invisible when character is out of camera view. This will stop the joint transforms update, except the root joint.
// Calling it after the bounds on the render actor updated.
if (!m_configuration.m_forceUpdateJointsOOV)
{
const bool isInCameraFrustum = m_renderActorInstance->IsInCameraFrustum();
m_actorInstance->SetIsVisible(isInCameraFrustum && m_configuration.m_renderCharacter);
m_actorInstance->SetIsVisible(isInCameraFrustum && renderActorSolid);
}
m_renderActorInstance->SetIsVisible(m_debugRenderFlags[RENDER_SOLID]);
// The configuration stores some debug option. When that is enabled, we override it on top of the render flags.
m_debugRenderFlags[RENDER_AABB] = m_debugRenderFlags[RENDER_AABB] || m_configuration.m_renderBounds;
m_debugRenderFlags[RENDER_LINESKELETON] = m_debugRenderFlags[RENDER_LINESKELETON] || m_configuration.m_renderSkeleton;
m_debugRenderFlags[RENDER_EMFX_DEBUG] = true;
m_renderActorInstance->DebugDraw(m_debugRenderFlags);
m_renderActorInstance->SetIsVisible(renderActorSolid);
m_renderActorInstance->DebugDraw(m_configuration.m_renderFlags);
}
}

@ -82,11 +82,9 @@ namespace EMotionFX
AZ::EntityId m_attachmentTarget{}; ///< Target entity this actor should attach to.
size_t m_attachmentJointIndex = InvalidIndex; ///< Index of joint on target skeleton for actor attachments.
AttachmentType m_attachmentType = AttachmentType::None; ///< Type of attachment.
bool m_renderSkeleton = false; ///< Toggles debug rendering of the skeleton.
bool m_renderCharacter = true; ///< Toggles rendering of the character.
bool m_renderBounds = false; ///< Toggles rendering of the character bounds used for visibility testing.
SkinningMethod m_skinningMethod = SkinningMethod::DualQuat; ///< The skinning method for this actor
size_t m_lodLevel = 0;
ActorRenderFlags m_renderFlags = ActorRenderFlags::Default; ///< Actor render flag
// Force updating the joints when it is out of camera view. By
// default, joints level update (beside the root joint) on
@ -180,7 +178,7 @@ namespace EMotionFX
bool IsPhysicsSceneSimulationFinishEventConnected() const;
AZ::Data::Asset<ActorAsset> GetActorAsset() const { return m_configuration.m_actorAsset; }
void SetRenderFlag(ActorRenderFlagBitset renderFlags);
void SetRenderFlag(ActorRenderFlags renderFlags);
private:
// AZ::TransformNotificationBus::MultiHandler
@ -202,7 +200,6 @@ namespace EMotionFX
AZStd::vector<AZ::EntityId> m_attachments;
AZStd::unique_ptr<RenderActorInstance> m_renderActorInstance;
ActorRenderFlagBitset m_debugRenderFlags; ///< Actor debug render flag
AzPhysics::SceneEvents::OnSceneSimulationFinishHandler m_sceneFinishSimHandler;
};

@ -124,12 +124,12 @@ namespace EMotionFX
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(0, &EditorActorComponent::m_renderCharacter,
"Draw character", "Toggles rendering of character mesh.")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnDebugDrawFlagChanged)
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnRenderFlagChanged)
->DataElement(0, &EditorActorComponent::m_renderSkeleton,
"Draw skeleton", "Toggles rendering of skeleton.")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnDebugDrawFlagChanged)
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnRenderFlagChanged)
->DataElement(0, &EditorActorComponent::m_renderBounds, "Draw bounds", "Toggles rendering of world space bounding boxes.")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnDebugDrawFlagChanged)
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnRenderFlagChanged)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &EditorActorComponent::m_skinningMethod,
"Skinning method", "Choose the skinning method this actor is using")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnSkinningMethodChanged)
@ -180,7 +180,6 @@ namespace EMotionFX
, m_lodLevel(0)
, m_actorAsset(AZ::Data::AssetLoadBehavior::NoLoad)
{
m_debugRenderFlags[RENDER_SOLID] = true;
}
//////////////////////////////////////////////////////////////////////////
@ -198,6 +197,7 @@ namespace EMotionFX
{
AzToolsFramework::Components::EditorComponentBase::Activate();
UpdateRenderFlags();
LoadActorAsset();
const AZ::EntityId entityId = GetEntityId();
@ -363,8 +363,9 @@ namespace EMotionFX
}
//////////////////////////////////////////////////////////////////////////
void EditorActorComponent::OnDebugDrawFlagChanged()
void EditorActorComponent::OnRenderFlagChanged()
{
UpdateRenderFlags();
if (m_renderSkeleton || m_renderBounds || m_renderCharacter)
{
AZ::TickBus::Handler::BusConnect();
@ -573,6 +574,23 @@ namespace EMotionFX
ToolsApplicationEvents::Bus::Broadcast(&ToolsApplicationEvents::InvalidatePropertyDisplay, Refresh_EntireTree);
}
void EditorActorComponent::UpdateRenderFlags()
{
m_renderFlags = ActorRenderFlags::None;
if (m_renderCharacter)
{
m_renderFlags |= ActorRenderFlags::Solid;
}
if (m_renderBounds)
{
m_renderFlags |= ActorRenderFlags::AABB;
}
if (m_renderSkeleton)
{
m_renderFlags |= ActorRenderFlags::LineSkeleton;
}
}
//////////////////////////////////////////////////////////////////////////
void EditorActorComponent::OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world)
{
@ -616,22 +634,16 @@ namespace EMotionFX
{
m_renderActorInstance->OnTick(deltaTime);
m_renderActorInstance->UpdateBounds();
m_debugRenderFlags[RENDER_AABB] = m_renderBounds;
m_debugRenderFlags[RENDER_LINESKELETON] = m_renderSkeleton;
m_debugRenderFlags[RENDER_EMFX_DEBUG] = true;
m_renderActorInstance->DebugDraw(m_debugRenderFlags);
m_renderActorInstance->DebugDraw(m_renderFlags);
}
}
void EditorActorComponent::BuildGameEntity(AZ::Entity* gameEntity)
{
UpdateRenderFlags();
ActorComponent::Configuration cfg;
cfg.m_actorAsset = m_actorAsset;
cfg.m_materialPerLOD = m_materialPerLOD;
cfg.m_renderSkeleton = m_renderSkeleton;
cfg.m_renderCharacter = m_renderCharacter;
cfg.m_renderBounds = m_renderBounds;
cfg.m_attachmentType = m_attachmentType;
cfg.m_attachmentTarget = m_attachmentTarget;
cfg.m_attachmentJointIndex = m_attachmentJointIndex;
@ -639,6 +651,7 @@ namespace EMotionFX
cfg.m_skinningMethod = m_skinningMethod;
cfg.m_bboxConfig = m_bboxConfig;
cfg.m_forceUpdateJointsOOV = m_forceUpdateJointsOOV;
cfg.m_renderFlags = m_renderFlags;
gameEntity->AddComponent(aznew ActorComponent(&cfg));
}
@ -861,7 +874,7 @@ namespace EMotionFX
void EditorActorComponent::CheckActorCreation()
{
// Enable/disable debug drawing.
OnDebugDrawFlagChanged();
OnRenderFlagChanged();
// Create actor instance.
auto* actorAsset = m_actorAsset.GetAs<ActorAsset>();
@ -964,9 +977,9 @@ namespace EMotionFX
}
}
void EditorActorComponent::SetRenderFlag(ActorRenderFlagBitset renderFlags)
void EditorActorComponent::SetRenderFlag(ActorRenderFlags renderFlags)
{
m_debugRenderFlags = renderFlags;
m_renderFlags = renderFlags;
}
} //namespace Integration
} // namespace EMotionFX

@ -104,7 +104,7 @@ namespace EMotionFX
ActorComponent::GetRequiredServices(required);
}
void SetRenderFlag(ActorRenderFlagBitset renderFlags);
void SetRenderFlag(ActorRenderFlags renderFlags);
static void Reflect(AZ::ReflectContext* context);
@ -114,7 +114,7 @@ namespace EMotionFX
void OnMaterialChanged();
void OnMaterialPerActorChanged();
void OnLODLevelChanged();
void OnDebugDrawFlagChanged();
void OnRenderFlagChanged();
void OnSkinningMethodChanged();
AZ::Crc32 OnAttachmentTypeChanged();
AZ::Crc32 OnAttachmentTargetChanged();
@ -124,6 +124,7 @@ namespace EMotionFX
bool AttachmentTargetJointVisibility();
AZStd::string AttachmentJointButtonText();
void InitializeMaterial(ActorAsset& actorAsset);
void UpdateRenderFlags();
void LaunchAnimationEditor(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType&);
@ -164,7 +165,7 @@ namespace EMotionFX
size_t m_lodLevel;
ActorComponent::BoundingBoxConfiguration m_bboxConfig;
bool m_forceUpdateJointsOOV = false;
ActorRenderFlagBitset m_debugRenderFlags; ///< Actor debug render flag
ActorRenderFlags m_renderFlags; ///< Actor render flag
// \todo attachmentTarget node nr
// Note: LOD work in progress. For now we use one material instead of a list of material, because we don't have the support for LOD with multiple scene files.

@ -34,7 +34,7 @@ namespace EMotionFX
virtual ~RenderActorInstance() = default;
virtual void OnTick(float timeDelta) = 0;
virtual void DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags) = 0;
virtual void DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags) = 0;
SkinningMethod GetSkinningMethod() const;
virtual void SetSkinningMethod(SkinningMethod skinningMethod);

@ -7,38 +7,87 @@
*/
#pragma once
#include <AzCore/std/containers/bitset.h>
#include <AzCore/Preprocessor/Enum.h>
#include <Atom/RHI.Reflect/Bits.h>
namespace EMotionFX
{
enum ActorRenderFlag
// The index of the render flag which is 0, 1, 2, 3.. based.
// Do not confuse this with the actual ActorRenderFlags::Type which is 1, 2, 4, 8.. based.
enum ActorRenderFlagIndex : AZ::u8
{
RENDER_SOLID = 0,
RENDER_WIREFRAME = 1,
RENDER_LIGHTING = 2,
RENDER_SHADOWS = 3,
RENDER_FACENORMALS = 4,
RENDER_VERTEXNORMALS = 5,
RENDER_TANGENTS = 6,
RENDER_AABB = 7,
RENDER_SKELETON = 8,
RENDER_LINESKELETON = 9,
RENDER_NODEORIENTATION = 10,
RENDER_NODENAMES = 11,
RENDER_GRID = 12,
RENDER_BACKFACECULLING = 13,
RENDER_ACTORBINDPOSE = 14,
RENDER_RAGDOLL_COLLIDERS = 15,
RENDER_RAGDOLL_JOINTLIMITS = 16,
RENDER_HITDETECTION_COLLIDERS = 17,
RENDER_USE_GRADIENTBACKGROUND = 18,
RENDER_MOTIONEXTRACTION = 19,
RENDER_CLOTH_COLLIDERS = 20,
RENDER_SIMULATEDOBJECT_COLLIDERS = 21,
RENDER_SIMULATEJOINTS = 22,
RENDER_EMFX_DEBUG = 23,
NUM_RENDERFLAGS = 24
SOLID = 0,
WIREFRAME = 1,
LIGHTING = 2,
SHADOWS = 3,
FACENORMALS = 4,
VERTEXNORMALS = 5,
TANGENTS = 6,
AABB = 7,
SKELETON = 8,
LINESKELETON = 9,
NODEORIENTATION = 10,
NODENAMES = 11,
GRID = 12,
BACKFACECULLING = 13,
ACTORBINDPOSE = 14,
RAGDOLL_COLLIDERS = 15,
RAGDOLL_JOINTLIMITS = 16,
HITDETECTION_COLLIDERS = 17,
USE_GRADIENTBACKGROUND = 18,
MOTIONEXTRACTION = 19,
CLOTH_COLLIDERS = 20,
SIMULATEDOBJECT_COLLIDERS = 21,
SIMULATEJOINTS = 22,
EMFX_DEBUG = 23,
NUM_RENDERFLAGINDEXES = 24
};
using ActorRenderFlagBitset = AZStd::bitset<ActorRenderFlag::NUM_RENDERFLAGS>;
//! A set of combinable flags which indicate which render option in turned on for the actor.
AZ_ENUM_CLASS_WITH_UNDERLYING_TYPE(ActorRenderFlags, AZ::u32,
(None, 0),
(Solid, AZ_BIT(ActorRenderFlagIndex::SOLID)),
(Wireframe, AZ_BIT(ActorRenderFlagIndex::WIREFRAME)),
(Lighting, AZ_BIT(ActorRenderFlagIndex::LIGHTING)),
(Default, Solid | Lighting),
(Shadows, AZ_BIT(ActorRenderFlagIndex::SHADOWS)),
(FaceNormals, AZ_BIT(ActorRenderFlagIndex::FACENORMALS)),
(VertexNormals, AZ_BIT(ActorRenderFlagIndex::VERTEXNORMALS)),
(Tangents, AZ_BIT(ActorRenderFlagIndex::TANGENTS)),
(AABB, AZ_BIT(ActorRenderFlagIndex::AABB)),
(Skeleton, AZ_BIT(ActorRenderFlagIndex::SKELETON)),
(LineSkeleton, AZ_BIT(ActorRenderFlagIndex::LINESKELETON)),
(NodeOrientation, AZ_BIT(ActorRenderFlagIndex::NODEORIENTATION)),
(NodeNames, AZ_BIT(ActorRenderFlagIndex::NODENAMES)),
(Grid, AZ_BIT(ActorRenderFlagIndex::GRID)),
(BackfaceCulling, AZ_BIT(ActorRenderFlagIndex::BACKFACECULLING)),
(ActorBindPose, AZ_BIT(ActorRenderFlagIndex::ACTORBINDPOSE)),
(RagdollColliders, AZ_BIT(ActorRenderFlagIndex::RAGDOLL_COLLIDERS)),
(RagdollJointLimits, AZ_BIT(ActorRenderFlagIndex::RAGDOLL_JOINTLIMITS)),
(HitDetectionColliders, AZ_BIT(ActorRenderFlagIndex::HITDETECTION_COLLIDERS)),
(UseGradientBackground, AZ_BIT(ActorRenderFlagIndex::USE_GRADIENTBACKGROUND)),
(MotionExtraction, AZ_BIT(ActorRenderFlagIndex::MOTIONEXTRACTION)),
(ClothColliders, AZ_BIT(ActorRenderFlagIndex::CLOTH_COLLIDERS)),
(SimulatedObjectColliders, AZ_BIT(ActorRenderFlagIndex::SIMULATEDOBJECT_COLLIDERS)),
(SimulatedJoints, AZ_BIT(ActorRenderFlagIndex::SIMULATEJOINTS)),
(EmfxDebug, AZ_BIT(ActorRenderFlagIndex::EMFX_DEBUG))
);
AZ_DEFINE_ENUM_BITWISE_OPERATORS(ActorRenderFlags);
class ActorRenderFlagUtil
{
public:
// Check the bit value with the offset start at 0 from the right.
// CheckBit(flags, 0) means check the last digit of the flags, CheckBit(flags, 1) means the second digit from right, etc.
static bool CheckBit(ActorRenderFlags flags, AZ::u8 offset)
{
return (flags & ActorRenderFlags(AZ_BIT(offset))) != ActorRenderFlags(0);
}
};
}
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(EMotionFX::ActorRenderFlags, "{2D2187FA-2C1A-4485-AF7C-AD34C0514105}");
}

@ -65,7 +65,7 @@ namespace EMotionFX
}
MOCK_METHOD1(OnTick, void(float));
MOCK_METHOD1(DebugDraw, void(const EMotionFX::ActorRenderFlagBitset&));
MOCK_METHOD1(DebugDraw, void(const EMotionFX::ActorRenderFlags&));
MOCK_CONST_METHOD0(IsVisible, bool());
MOCK_METHOD1(SetIsVisible, void(bool));
MOCK_METHOD1(SetMaterials, void(const ActorAsset::MaterialList&));

Loading…
Cancel
Save