Add **Animation Instance Data node to Anim Graph** for caching value per-model

This commit is contained in:
Wojtek Figat
2023-02-14 12:39:58 +01:00
parent 77e19e148b
commit 835127ac21
4 changed files with 42 additions and 3 deletions

View File

@@ -973,6 +973,19 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.TextBox(30, Surface.Constants.LayoutOffsetY, 140, TextBox.DefaultHeight, 0, false),
}
},
new NodeArchetype
{
TypeID = 33,
Title = "Animation Instance Data",
Description = "Caches custom data per-instance and allow sampling it. Can be used to randomize animation play offset to offer randomization for crowds reusing the same graph.",
Flags = NodeFlags.AnimGraph,
Size = new Float2(240, 20),
Elements = new[]
{
NodeElementArchetype.Factory.Output(0, "Get", typeof(Float4), 0),
NodeElementArchetype.Factory.Input(0, "Init", true, typeof(Float4), 1),
}
},
};
}
}

View File

@@ -115,6 +115,11 @@ void SlotBucketInit(AnimGraphInstanceData::Bucket& bucket)
bucket.Slot.LoopsLeft = 0;
}
void InstanceDataBucketInit(AnimGraphInstanceData::Bucket& bucket)
{
bucket.InstanceData.Init = true;
}
bool SortMultiBlend1D(const byte& a, const byte& b, AnimGraphNode* n)
{
// Sort items by X location from the lowest to the highest
@@ -432,10 +437,12 @@ bool AnimGraphBase::onNodeLoaded(Node* n)
}
// Animation Slot
case 32:
{
ADD_BUCKET(SlotBucketInit);
break;
}
// Animation Instance Data
case 33:
ADD_BUCKET(InstanceDataBucketInit);
break;
}
break;
// Custom

View File

@@ -315,6 +315,12 @@ public:
int32 LoopsLeft;
};
struct InstanceDataBucket
{
bool Init;
float Data[4];
};
/// <summary>
/// The single data storage bucket for the instanced animation graph node. Used to store the node state (playback position, state, transition data).
/// </summary>
@@ -327,6 +333,7 @@ public:
BlendPoseBucket BlendPose;
StateMachineBucket StateMachine;
SlotBucket Slot;
InstanceDataBucket InstanceData;
};
};

View File

@@ -2035,10 +2035,22 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
}
break;
}
// Animation Instance Data
case 33:
{
auto& bucket = context.Data->State[node->BucketIndex].InstanceData;
if (bucket.Init)
{
bucket.Init = false;
*(Float4*)bucket.Data = (Float4)tryGetValue(node->GetBox(1), Value::Zero);
}
value = *(Float4*)bucket.Data;
break;
}
default:
break;
}
context.ValueCache.Add(boxBase, value);
context.ValueCache[boxBase] = value;
}
void AnimGraphExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value& value)