Added box expansion percentage to the (editor)actor components

Signed-off-by: Benjamin Jillich <jillich@amazon.com>
This commit is contained in:
Benjamin Jillich
2021-08-05 15:09:00 +02:00
parent d134deee1d
commit 60fa18ec27
3 changed files with 71 additions and 44 deletions
@@ -58,27 +58,32 @@ namespace EMotionFX
};
//////////////////////////////////////////////////////////////////////////
void ActorComponent::BoundingBoxConfiguration::Set(ActorInstance* actor) const
void ActorComponent::BoundingBoxConfiguration::Set(ActorInstance* actorInstance) const
{
actorInstance->SetExpandBoundsBy(m_expandBy * 0.01f); // Normalize percentage for internal use. (1% == 0.01f)
if (m_autoUpdateBounds)
{
actor->SetupAutoBoundsUpdate(m_updateTimeFrequency, m_boundsType, m_updateItemFrequency);
actorInstance->SetupAutoBoundsUpdate(m_updateTimeFrequency, m_boundsType, m_updateItemFrequency);
}
else
{
actor->SetBoundsUpdateType(m_boundsType);
actor->SetBoundsUpdateEnabled(false);
actorInstance->SetBoundsUpdateType(m_boundsType);
actorInstance->SetBoundsUpdateEnabled(false);
}
}
void ActorComponent::BoundingBoxConfiguration::SetAndUpdate(ActorInstance* actor) const
void ActorComponent::BoundingBoxConfiguration::SetAndUpdate(ActorInstance* actorInstance) const
{
Set(actor);
const AZ::u32 freq = actor->GetBoundsUpdateEnabled() ? actor->GetBoundsUpdateItemFrequency() : 1;
actor->UpdateBounds(0, actor->GetBoundsUpdateType(), freq);
Set(actorInstance);
const AZ::u32 updateFrequency = actorInstance->GetBoundsUpdateEnabled() ? actorInstance->GetBoundsUpdateItemFrequency() : 1;
const ActorInstance::EBoundsType boundUpdateType = actorInstance->GetBoundsUpdateType();
actorInstance->UpdateBounds(actorInstance->GetLODLevel(), boundUpdateType, updateFrequency);
}
void ActorComponent::BoundingBoxConfiguration::Reflect(AZ::ReflectContext * context)
void ActorComponent::BoundingBoxConfiguration::Reflect(AZ::ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
@@ -105,10 +110,26 @@ namespace EMotionFX
->Field("m_autoUpdateBounds", &BoundingBoxConfiguration::m_autoUpdateBounds)
->Field("m_updateTimeFrequency", &BoundingBoxConfiguration::m_updateTimeFrequency)
->Field("m_updateItemFrequency", &BoundingBoxConfiguration::m_updateItemFrequency)
->Field("expandBy", &BoundingBoxConfiguration::m_expandBy)
;
}
}
AZ::Crc32 ActorComponent::BoundingBoxConfiguration::GetVisibilityAutoUpdate() const
{
return m_boundsType != EMotionFX::ActorInstance::BOUNDS_STATIC_BASED ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
}
AZ::Crc32 ActorComponent::BoundingBoxConfiguration::GetVisibilityAutoUpdateSettings() const
{
if (m_boundsType == EMotionFX::ActorInstance::BOUNDS_STATIC_BASED || m_autoUpdateBounds == false)
{
return AZ::Edit::PropertyVisibility::Hide;
}
return AZ::Edit::PropertyVisibility::Show;
}
//////////////////////////////////////////////////////////////////////////
void ActorComponent::Configuration::Reflect(AZ::ReflectContext* context)
{
@@ -45,24 +45,29 @@ namespace EMotionFX
AZ_COMPONENT(ActorComponent, "{BDC97E7F-A054-448B-A26F-EA2B5D78E377}");
friend class EditorActorComponent;
struct BoundingBoxConfiguration
class BoundingBoxConfiguration
{
public:
AZ_TYPE_INFO(BoundingBoxConfiguration, "{EBCFF975-00A5-4578-85C7-59909F52067C}");
BoundingBoxConfiguration() = default;
EMotionFX::ActorInstance::EBoundsType m_boundsType = EMotionFX::ActorInstance::BOUNDS_STATIC_BASED;
bool m_autoUpdateBounds = true;
float m_updateTimeFrequency = 0.f;
AZ::u32 m_updateItemFrequency = 1;
EMotionFX::ActorInstance::EBoundsType m_boundsType = EMotionFX::ActorInstance::BOUNDS_STATIC_BASED;
float m_expandBy = 25.0f; ///< Expand the bounding volume by the given percentage.
bool m_autoUpdateBounds = true;
float m_updateTimeFrequency = 0.0f;
AZ::u32 m_updateItemFrequency = 1;
// Set the bounding box configuration of the given actor instance to the parameters given by `this'. The actor instance must not be null (this is not checked).
void Set(ActorInstance* inst) const;
// Set the bounding box configuration of the given actor instance to the parameters given by 'this'. The actor instance must not be null (this is not checked).
void Set(ActorInstance* actorInstance) const;
// Set the bounding box configuration, then update the bounds of the actor instance
void SetAndUpdate(ActorInstance* inst) const;
void SetAndUpdate(ActorInstance* actorInstance) const;
static void Reflect(AZ::ReflectContext* context);
AZ::Crc32 GetVisibilityAutoUpdate() const;
AZ::Crc32 GetVisibilityAutoUpdateSettings() const;
};
/**
@@ -62,39 +62,40 @@ namespace EMotionFX
{
editContext->Class<ActorComponent::BoundingBoxConfiguration>("Actor Bounding Box Config", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &ActorComponent::BoundingBoxConfiguration::m_boundsType,
"Bounds type",
"The method used to compute the Actor bounding box. NOTE: ordered by least expensive to compute to most expensive to compute."
)
->EnumAttribute(ActorInstance::BOUNDS_STATIC_BASED, "Static bounds (source-asset bounds)")
->EnumAttribute(ActorInstance::BOUNDS_NODE_BASED, "Bone position-based")
->EnumAttribute(ActorInstance::BOUNDS_NODEOBB_BASED, "Bone local bounding box-based")
->EnumAttribute(ActorInstance::BOUNDS_MESH_BASED, "Render mesh vertex position-based (VERY EXPENSIVE)")
->DataElement(0, &ActorComponent::BoundingBoxConfiguration::m_autoUpdateBounds,
"The method used to compute the Actor bounding box. NOTE: ordered by least expensive to compute to most expensive to compute.")
->EnumAttribute(ActorInstance::BOUNDS_STATIC_BASED, "Static (Recommended)")
->EnumAttribute(ActorInstance::BOUNDS_NODE_BASED, "Bone position-based")
->EnumAttribute(ActorInstance::BOUNDS_MESH_BASED, "Mesh vertex-based (Expensive)")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->DataElement(AZ::Edit::UIHandlers::Default, &ActorComponent::BoundingBoxConfiguration::m_expandBy,
"Expand by",
"Percentage that the calculated bounding box should be automatically expanded with. "
"This can be used to add a tolerance area to the calculated bounding box to avoid clipping the character too early. "
"A static bounding box together with the expansion is the recommended way for maximum performance. (Default = 25%)")
->Attribute(AZ::Edit::Attributes::Suffix, " %")
->Attribute(AZ::Edit::Attributes::Min, 0.0f)
->DataElement(AZ::Edit::UIHandlers::Default, &ActorComponent::BoundingBoxConfiguration::m_autoUpdateBounds,
"Automatically update bounds?",
"If true, bounds are automatically updated based on some frequency. Otherwise bounds are computed only at creation or when triggered manually"
)
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
->DataElement(0, &ActorComponent::BoundingBoxConfiguration::m_updateTimeFrequency,
"If true, bounds are automatically updated based on some frequency. Otherwise bounds are computed only at creation or when triggered manually")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->Attribute(AZ::Edit::Attributes::Visibility, &ActorComponent::BoundingBoxConfiguration::GetVisibilityAutoUpdate)
->DataElement(AZ::Edit::UIHandlers::Default, &ActorComponent::BoundingBoxConfiguration::m_updateTimeFrequency,
"Update frequency",
"How often to update bounds automatically"
)
->Attribute(AZ::Edit::Attributes::Suffix, " Hz")
->Attribute(AZ::Edit::Attributes::Min, 0.f)
->Attribute(AZ::Edit::Attributes::Step, 0.001f)
->Attribute(AZ::Edit::Attributes::Visibility, &ActorComponent::BoundingBoxConfiguration::m_autoUpdateBounds)
->DataElement(0, &ActorComponent::BoundingBoxConfiguration::m_updateItemFrequency,
"How often to update bounds automatically")
->Attribute(AZ::Edit::Attributes::Suffix, " Hz")
->Attribute(AZ::Edit::Attributes::Min, 0.0f)
->Attribute(AZ::Edit::Attributes::Max, FLT_MAX)
->Attribute(AZ::Edit::Attributes::Step, 0.1f)
->Attribute(AZ::Edit::Attributes::Visibility, &ActorComponent::BoundingBoxConfiguration::GetVisibilityAutoUpdateSettings)
->DataElement(AZ::Edit::UIHandlers::Default, &ActorComponent::BoundingBoxConfiguration::m_updateItemFrequency,
"Update item skip factor",
"How many items (bones or vertices) to skip when automatically updating bounds."
" <br> i.e. =1 uses every single item, =2 uses every 2nd item, =3 uses every 3rd item... "
)
->Attribute(AZ::Edit::Attributes::Suffix, " items")
->Attribute(AZ::Edit::Attributes::Min, (AZ::u32)1)
->Attribute(AZ::Edit::Attributes::Visibility, &ActorComponent::BoundingBoxConfiguration::m_autoUpdateBounds)
" <br> i.e. =1 uses every single item, =2 uses every 2nd item, =3 uses every 3rd item...")
->Attribute(AZ::Edit::Attributes::Suffix, " items")
->Attribute(AZ::Edit::Attributes::Min, (AZ::u32)1)
->Attribute(AZ::Edit::Attributes::Visibility, &ActorComponent::BoundingBoxConfiguration::GetVisibilityAutoUpdateSettings)
;
editContext->Class<EditorActorComponent>("Actor", "The Actor component manages an instance of an Actor")