Optimize Anim Graph node size and remove limit of max 64 state transitions

This commit is contained in:
Wojtek Figat
2024-04-19 16:31:11 +02:00
parent 7653fba381
commit 93e26afa05
4 changed files with 17 additions and 19 deletions

View File

@@ -380,6 +380,7 @@ bool AnimGraphBase::onNodeLoaded(Node* n)
void AnimGraphBase::LoadStateTransitions(AnimGraphNode::StateBaseData& data, Value& transitionsData)
{
int32 validTransitions = 0;
data.Transitions = nullptr;
if (transitionsData.Type == VariantType::Blob && transitionsData.AsBlob.Length)
{
MemoryReadStream stream((byte*)transitionsData.AsBlob.Data, transitionsData.AsBlob.Length);
@@ -394,8 +395,11 @@ void AnimGraphBase::LoadStateTransitions(AnimGraphNode::StateBaseData& data, Val
int32 transitionsCount;
stream.ReadInt32(&transitionsCount);
if (transitionsCount == 0)
return;
StateTransitions.EnsureCapacity(StateTransitions.Count() + transitionsCount);
data.Transitions = (uint16*)Allocator::Allocate(transitionsCount * sizeof(uint16));
AnimGraphStateTransition transition;
for (int32 i = 0; i < transitionsCount; i++)
@@ -430,7 +434,6 @@ void AnimGraphBase::LoadStateTransitions(AnimGraphNode::StateBaseData& data, Val
// Skip disabled transitions
continue;
}
if (ruleSize != 0)
{
transition.RuleGraph = LoadSubGraph(ruleBytes, ruleSize, TEXT("Rule"));
@@ -440,25 +443,19 @@ void AnimGraphBase::LoadStateTransitions(AnimGraphNode::StateBaseData& data, Val
continue;
}
}
if (transition.Destination == nullptr)
{
LOG(Warning, "Missing target node for the state machine transition.");
continue;
}
if (validTransitions == ANIM_GRAPH_MAX_STATE_TRANSITIONS)
{
LOG(Warning, "State uses too many transitions.");
continue;
}
data.Transitions[validTransitions++] = (uint16)StateTransitions.Count();
StateTransitions.Add(transition);
}
}
if (validTransitions != ANIM_GRAPH_MAX_STATE_TRANSITIONS)
// Last entry is invalid to indicate end
data.Transitions[validTransitions] = AnimGraphNode::StateData::InvalidTransitionIndex;
}
// Release data to don't use that memory
transitionsData = AnimGraphExecutor::Value::Null;

View File

@@ -119,6 +119,12 @@ AnimGraphNode::~AnimGraphNode()
case 13:
Allocator::Free(Data.MultiBlend2D.Triangles);
break;
// State
case 20:
// Any State
case 34:
Allocator::Free(Data.State.Transitions);
break;
}
break;
}

View File

@@ -15,7 +15,6 @@
#define ANIM_GRAPH_IS_VALID_PTR(value) (value.Type.Type == VariantType::Pointer && value.AsPointer != nullptr)
#define ANIM_GRAPH_MULTI_BLEND_INDEX byte
#define ANIM_GRAPH_MULTI_BLEND_INVALID 0xff
#define ANIM_GRAPH_MAX_STATE_TRANSITIONS 64
#define ANIM_GRAPH_MAX_CALL_STACK 100
#define ANIM_GRAPH_MAX_EVENTS 64
@@ -464,15 +463,11 @@ public:
struct StateBaseData
{
/// <summary>
/// The invalid transition valid used in Transitions to indicate invalid transition linkage.
/// </summary>
// The invalid transition valid used in Transitions to indicate invalid transition linkage.
const static uint16 InvalidTransitionIndex = MAX_uint16;
/// <summary>
/// The outgoing transitions from this state to the other states. Each array item contains index of the transition data from the state node graph transitions cache. Value InvalidTransitionIndex is used for last transition to indicate the transitions amount.
/// </summary>
uint16 Transitions[ANIM_GRAPH_MAX_STATE_TRANSITIONS];
// The outgoing transitions from this state to the other states. Each array item contains index of the transition data from the state node graph transitions cache. Value InvalidTransitionIndex is used for last transition to indicate the transitions amount.
uint16* Transitions;
};
struct StateData : StateBaseData

View File

@@ -585,7 +585,7 @@ AnimGraphStateTransition* AnimGraphExecutor::UpdateStateTransitions(AnimGraphCon
AnimGraphStateTransition* AnimGraphExecutor::UpdateStateTransitions(AnimGraphContext& context, const AnimGraphNode::StateMachineData& stateMachineData, const AnimGraphNode::StateBaseData& stateData, AnimGraphNode* state, AnimGraphNode* ignoreState)
{
int32 transitionIndex = 0;
while (transitionIndex < ANIM_GRAPH_MAX_STATE_TRANSITIONS && stateData.Transitions[transitionIndex] != AnimGraphNode::StateData::InvalidTransitionIndex)
while (stateData.Transitions && stateData.Transitions[transitionIndex] != AnimGraphNode::StateData::InvalidTransitionIndex)
{
const uint16 idx = stateData.Transitions[transitionIndex];
ASSERT(idx < stateMachineData.Graph->StateTransitions.Count());