Added test for synced blending of embedded blend tree.
This commit is contained in:
parent
d01c6fb474
commit
a098bc1171
@ -257,8 +257,7 @@ public:
|
||||
double sync_position = 0.0;
|
||||
bool is_synced = false;
|
||||
|
||||
// TODO: 2026-02-17: how to initialize loop_mode e.g. for a BlendTree or a StateMachine?
|
||||
Animation::LoopMode loop_mode = Animation::LOOP_LINEAR;
|
||||
Animation::LoopMode loop_mode = Animation::LOOP_NONE;
|
||||
SyncTrack sync_track;
|
||||
};
|
||||
NodeTimeInfo node_time_info;
|
||||
@ -753,6 +752,8 @@ public:
|
||||
}
|
||||
|
||||
tree_graph.nodes[0]->active = true;
|
||||
tree_graph.nodes[0]->node_time_info.is_synced = node_time_info.is_synced;
|
||||
|
||||
for (uint32_t i = 0; i < tree_graph.nodes.size(); i++) {
|
||||
const Ref<BLTAnimationNode> &node = tree_graph.nodes[i];
|
||||
|
||||
@ -777,14 +778,21 @@ public:
|
||||
const NodeRuntimeData &node_runtime_data = _node_runtime_data[i];
|
||||
|
||||
node->calculate_sync_track(node_runtime_data.input_nodes);
|
||||
|
||||
if (i == 1) {
|
||||
node_time_info = node->node_time_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_time(double p_delta) override {
|
||||
GodotProfileZone("SyncedBlendTree::update_time");
|
||||
|
||||
tree_graph.nodes[0]->node_time_info.delta = p_delta;
|
||||
tree_graph.nodes[0]->node_time_info.position += p_delta;
|
||||
BLTAnimationNode::update_time(p_delta);
|
||||
|
||||
tree_graph.nodes[0]->node_time_info.delta = node_time_info.delta;
|
||||
tree_graph.nodes[0]->node_time_info.position = node_time_info.position;
|
||||
tree_graph.nodes[0]->node_time_info.sync_position = node_time_info.sync_position;
|
||||
|
||||
for (uint32_t i = 1; i < tree_graph.nodes.size(); i++) {
|
||||
const Ref<BLTAnimationNode> &node = tree_graph.nodes[i];
|
||||
|
||||
@ -8,7 +8,28 @@ animation = &"Walk-InPlace"
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_lquwl"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vyt75"]
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_hom0r"]
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_vyt75"]
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_1rfsi"]
|
||||
nodes/BlendTree/node = SubResource("AnimationNodeBlendTree_vyt75")
|
||||
nodes/BlendTree/position = Vector2(694.9995, 215.55058)
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_8tpve"]
|
||||
graph_offset = Vector2(-782, 179.47485)
|
||||
nodes/Animation/node = SubResource("AnimationNodeAnimation_vyt75")
|
||||
nodes/Animation/position = Vector2(-320, 140)
|
||||
nodes/Blend2/node = SubResource("AnimationNodeBlend2_hom0r")
|
||||
nodes/Blend2/position = Vector2(-115.66393, 127.37674)
|
||||
nodes/BlendTree/node = SubResource("AnimationNodeBlendTree_1rfsi")
|
||||
nodes/BlendTree/position = Vector2(-480, 400)
|
||||
node_connections = [&"output", 0, &"Blend2", &"Blend2", 0, &"Animation", &"Blend2", 1, &"BlendTree"]
|
||||
|
||||
[resource]
|
||||
graph_offset = Vector2(-217.4643, 82.84979)
|
||||
nodes/output/position = Vector2(540, 140)
|
||||
nodes/Animation/node = SubResource("AnimationNodeAnimation_1bvp3")
|
||||
nodes/Animation/position = Vector2(120, 80)
|
||||
@ -16,4 +37,6 @@ nodes/Animation/position = Vector2(120, 80)
|
||||
"nodes/Animation 2/position" = Vector2(80, 320)
|
||||
nodes/Blend2/node = SubResource("AnimationNodeBlend2_lquwl")
|
||||
nodes/Blend2/position = Vector2(360, 180)
|
||||
nodes/BlendTree/node = SubResource("AnimationNodeBlendTree_8tpve")
|
||||
nodes/BlendTree/position = Vector2(778.0867, 295.33868)
|
||||
node_connections = [&"output", 0, &"Blend2", &"Blend2", 0, &"Animation", &"Blend2", 1, &"Animation 2"]
|
||||
|
||||
@ -34,6 +34,7 @@ glow_enabled = true
|
||||
[sub_resource type="BLTAnimationNodeBlend2" id="BLTAnimationNodeBlend2_7mycd"]
|
||||
resource_name = "BLTAnimationNodeBlend2"
|
||||
position = Vector2(-320, -40)
|
||||
blend_amount = 0.81
|
||||
|
||||
[sub_resource type="BLTAnimationNodeSampler" id="BLTAnimationNodeSampler_272bh"]
|
||||
resource_name = "BLTAnimationNodeSampler"
|
||||
@ -43,7 +44,7 @@ animation = &"animation_library/Walk-InPlace"
|
||||
[sub_resource type="BLTAnimationNodeBlendTree" id="BLTAnimationNodeBlendTree_5vw27"]
|
||||
resource_name = "BLTAnimationNodeBlendTree"
|
||||
position = Vector2(-640, -20)
|
||||
graph_offset = Vector2(-766.67163, -102.823944)
|
||||
graph_offset = Vector2(-760.67163, -24.823944)
|
||||
nodes/BLTAnimationNodeSampler/node = SubResource("BLTAnimationNodeSampler_272bh")
|
||||
nodes/BLTAnimationNodeSampler/graph_offset = Vector2(-490, 7)
|
||||
node_connections = ["Output", 0, "BLTAnimationNodeSampler"]
|
||||
@ -51,11 +52,11 @@ node_connections = ["Output", 0, "BLTAnimationNodeSampler"]
|
||||
[sub_resource type="BLTAnimationNodeSampler" id="BLTAnimationNodeSampler_kek77"]
|
||||
resource_name = "BLTAnimationNodeSampler"
|
||||
position = Vector2(-620, 140)
|
||||
animation = &"animation_library/Walk-InPlace"
|
||||
animation = &"animation_library/Run-InPlace"
|
||||
|
||||
[sub_resource type="BLTAnimationNodeBlendTree" id="BLTAnimationNodeBlendTree_7mycd"]
|
||||
resource_name = "Root"
|
||||
graph_offset = Vector2(-1054.4585, -50.771484)
|
||||
graph_offset = Vector2(-869, -71)
|
||||
nodes/BLTAnimationNodeBlend2/node = SubResource("BLTAnimationNodeBlend2_7mycd")
|
||||
nodes/BLTAnimationNodeBlend2/graph_offset = Vector2(-320, -40)
|
||||
nodes/BLTAnimationNodeSampler/node = SubResource("BLTAnimationNodeSampler_kek77")
|
||||
@ -318,7 +319,7 @@ libraries/animation_library = ExtResource("3_1bvp3")
|
||||
animation_player = NodePath("../AnimationPlayer2")
|
||||
tree_root = SubResource("BLTAnimationNodeBlendTree_7mycd")
|
||||
skeleton = NodePath("../Armature/Skeleton3D")
|
||||
parameters/BLTAnimationNodeBlend2/blend_amount = 0.0
|
||||
parameters/BLTAnimationNodeBlend2/blend_amount = 0.81
|
||||
|
||||
[connection signal="value_changed" from="UI/MarginContainer/HBoxContainer/BlendWeightSlider" to="." method="_on_blend_weight_slider_value_changed"]
|
||||
|
||||
|
||||
@ -607,7 +607,6 @@ TEST_CASE_FIXTURE(BlendTreeFixture, "[SceneTree][Blendalot][BlendTreeGraph][Embe
|
||||
// TestAnimationB
|
||||
Ref<BLTAnimationNodeSampler> animation_sampler_node_b;
|
||||
animation_sampler_node_b.instantiate();
|
||||
animation_sampler_node_b->animation_name = "animation_library/TestAnimationB";
|
||||
|
||||
embedded_blend_tree->add_node(animation_sampler_node_b);
|
||||
embedded_blend_tree->add_connection(animation_sampler_node_b, embedded_blend_tree->get_output_node(), "Output");
|
||||
@ -619,15 +618,11 @@ TEST_CASE_FIXTURE(BlendTreeFixture, "[SceneTree][Blendalot][BlendTreeGraph][Embe
|
||||
Ref<BLTAnimationNodeBlend2> blend2;
|
||||
blend2.instantiate();
|
||||
blend2->set_name("Blend2");
|
||||
blend2->blend_weight = 0.5;
|
||||
blend2->sync = true;
|
||||
|
||||
blend_tree->add_node(blend2);
|
||||
|
||||
// TestAnimationA
|
||||
Ref<BLTAnimationNodeSampler> animation_sampler_node_a;
|
||||
animation_sampler_node_a.instantiate();
|
||||
animation_sampler_node_a->animation_name = "animation_library/TestAnimationA";
|
||||
|
||||
blend_tree->add_node(animation_sampler_node_a);
|
||||
|
||||
@ -637,6 +632,12 @@ TEST_CASE_FIXTURE(BlendTreeFixture, "[SceneTree][Blendalot][BlendTreeGraph][Embe
|
||||
blend_tree->add_connection(embedded_blend_tree, blend2, "Input1");
|
||||
blend_tree->add_connection(blend2, blend_tree->get_output_node(), "Output");
|
||||
|
||||
SUBCASE("Perform regular blend") {
|
||||
animation_sampler_node_b->animation_name = "animation_library/TestAnimationB";
|
||||
animation_sampler_node_a->animation_name = "animation_library/TestAnimationA";
|
||||
blend2->blend_weight = 0.5;
|
||||
blend2->sync = false;
|
||||
|
||||
// Trigger initialization
|
||||
animation_graph->set_root_animation_node(blend_tree);
|
||||
GraphEvaluationContext &graph_context = animation_graph->get_context();
|
||||
@ -654,6 +655,31 @@ TEST_CASE_FIXTURE(BlendTreeFixture, "[SceneTree][Blendalot][BlendTreeGraph][Embe
|
||||
CHECK(hip_transform_value->loc[0] == doctest::Approx(0.15));
|
||||
CHECK(hip_transform_value->loc[1] == doctest::Approx(0.3));
|
||||
CHECK(hip_transform_value->loc[2] == doctest::Approx(0.45));
|
||||
}
|
||||
SUBCASE("Perform synced blend") {
|
||||
animation_sampler_node_b->animation_name = "animation_library/TestAnimationSyncA";
|
||||
animation_sampler_node_a->animation_name = "animation_library/TestAnimationSyncB";
|
||||
blend2->blend_weight = 0.5;
|
||||
blend2->sync = true;
|
||||
|
||||
// Trigger initialization
|
||||
animation_graph->set_root_animation_node(blend_tree);
|
||||
GraphEvaluationContext &graph_context = animation_graph->get_context();
|
||||
REQUIRE(blend_tree->initialize(graph_context));
|
||||
|
||||
// Perform evaluation
|
||||
AnimationData *graph_output = graph_context.animation_data_allocator.allocate();
|
||||
blend_tree->activate_inputs(Vector<Ref<BLTAnimationNode>>());
|
||||
blend_tree->calculate_sync_track(Vector<Ref<BLTAnimationNode>>());
|
||||
blend_tree->update_time(0.825);
|
||||
blend_tree->evaluate(graph_context, LocalVector<AnimationData *>(), *graph_output);
|
||||
|
||||
// Check values
|
||||
AnimationData::TransformTrackValue *hip_transform_value = graph_output->get_value<AnimationData::TransformTrackValue>(test_animation_a->get_tracks()[0]->thash);
|
||||
CHECK(hip_transform_value->loc[0] == doctest::Approx(1.5));
|
||||
CHECK(hip_transform_value->loc[1] == doctest::Approx(3.0));
|
||||
CHECK(hip_transform_value->loc[2] == doctest::Approx(4.5));
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace TestBlendalotAnimationGraph
|
||||
Loading…
x
Reference in New Issue
Block a user