Added support of time updates for simple embedded graphs.
This commit is contained in:
@@ -140,7 +140,9 @@ class EmbeddedBlendTreeGraphResource {
|
||||
BlendTreeResource* embedded_blend_tree_resource = nullptr;
|
||||
|
||||
size_t walk_node_index = -1;
|
||||
AnimNodeResource* walk_node = nullptr;
|
||||
AnimNodeResource* walk_node_resource = nullptr;
|
||||
size_t embedded_blend_tree_node_index = -1;
|
||||
size_t embedded_speed_scale_index = -1;
|
||||
|
||||
public:
|
||||
EmbeddedBlendTreeGraphResource() {
|
||||
@@ -163,10 +165,11 @@ class EmbeddedBlendTreeGraphResource {
|
||||
// Parent AnimSampler
|
||||
parent_blend_tree_resource->m_nodes.push_back(
|
||||
AnimNodeResourceFactory("AnimSampler"));
|
||||
walk_node_index = parent_blend_tree_resource->m_nodes.size() - 1;
|
||||
|
||||
walk_node = parent_blend_tree_resource->m_nodes.back();
|
||||
walk_node->m_name = "WalkAnim";
|
||||
walk_node->m_socket_accessor->SetPropertyValue(
|
||||
walk_node_resource = parent_blend_tree_resource->m_nodes[walk_node_index];
|
||||
walk_node_resource->m_name = "WalkAnim";
|
||||
walk_node_resource->m_socket_accessor->SetPropertyValue(
|
||||
"Filename",
|
||||
std::string("media/Walking-loop.ozz"));
|
||||
|
||||
@@ -175,7 +178,7 @@ class EmbeddedBlendTreeGraphResource {
|
||||
//
|
||||
parent_blend_tree_resource->m_nodes.push_back(
|
||||
AnimNodeResourceFactory("BlendTree"));
|
||||
size_t embedded_blend_tree_node_index =
|
||||
embedded_blend_tree_node_index =
|
||||
parent_blend_tree_resource->m_nodes.size() - 1;
|
||||
embedded_graph = dynamic_cast<AnimGraphResource*>(
|
||||
parent_blend_tree_resource->m_nodes.back());
|
||||
@@ -201,9 +204,13 @@ class EmbeddedBlendTreeGraphResource {
|
||||
// Embedded: SpeedScale node
|
||||
embedded_blend_tree_resource->m_nodes.push_back(
|
||||
AnimNodeResourceFactory("SpeedScale"));
|
||||
embedded_speed_scale_index =
|
||||
embedded_blend_tree_resource->m_nodes.size() - 1;
|
||||
AnimNodeResource* embedded_speed_scale_resource =
|
||||
embedded_blend_tree_resource->m_nodes.back();
|
||||
embedded_speed_scale_resource->m_socket_accessor->SetInputValue("SpeedScale", 0.1f);
|
||||
embedded_blend_tree_resource->m_nodes[embedded_speed_scale_index];
|
||||
embedded_speed_scale_resource->m_socket_accessor->SetInputValue(
|
||||
"SpeedScale",
|
||||
0.1f);
|
||||
|
||||
// Embedded: setup connections
|
||||
embedded_blend_tree_resource->ConnectSockets(
|
||||
@@ -219,7 +226,7 @@ class EmbeddedBlendTreeGraphResource {
|
||||
|
||||
// Parent: setup connections
|
||||
REQUIRE(parent_blend_tree_resource->ConnectSockets(
|
||||
walk_node,
|
||||
walk_node_resource,
|
||||
"Output",
|
||||
embedded_graph,
|
||||
"AnimInput"));
|
||||
@@ -346,8 +353,8 @@ TEST_CASE_METHOD(
|
||||
AnimSamplerNode* anim_sampler_walk =
|
||||
dynamic_cast<AnimSamplerNode*>(anim_graph_blend_tree.m_nodes[2]);
|
||||
|
||||
BlendTreeNode* graph_output_node =
|
||||
dynamic_cast<BlendTreeNode*>(anim_graph_blend_tree.m_nodes[0]);
|
||||
BlendTreeSocketNode* graph_output_node =
|
||||
dynamic_cast<BlendTreeSocketNode*>(anim_graph_blend_tree.m_nodes[0]);
|
||||
|
||||
// check node input dependencies
|
||||
size_t anim_sampler_index =
|
||||
@@ -937,7 +944,8 @@ TEST_CASE_METHOD(
|
||||
parent_blend_tree_resource->m_nodes.size()
|
||||
== parent_blend_tree_resource_loaded.m_nodes.size());
|
||||
for (size_t i = 0; i < parent_blend_tree_resource->m_nodes.size(); i++) {
|
||||
const AnimNodeResource* parent_node = parent_blend_tree_resource->m_nodes[i];
|
||||
const AnimNodeResource* parent_node =
|
||||
parent_blend_tree_resource->m_nodes[i];
|
||||
const AnimNodeResource* parent_node_loaded =
|
||||
parent_blend_tree_resource_loaded.m_nodes[i];
|
||||
|
||||
@@ -949,7 +957,8 @@ TEST_CASE_METHOD(
|
||||
CHECK(
|
||||
parent_blend_tree_resource->m_connections.size()
|
||||
== parent_blend_tree_resource_loaded.m_connections.size());
|
||||
for (size_t i = 0; i < parent_blend_tree_resource->m_connections.size(); i++) {
|
||||
for (size_t i = 0; i < parent_blend_tree_resource->m_connections.size();
|
||||
i++) {
|
||||
const BlendTreeConnectionResource& parent_connection =
|
||||
parent_blend_tree_resource->m_connections[i];
|
||||
const BlendTreeConnectionResource& parent_connection_loaded =
|
||||
@@ -1039,22 +1048,61 @@ TEST_CASE_METHOD(
|
||||
graph_context.m_skeleton = &skeleton;
|
||||
|
||||
blend_tree.Init(graph_context);
|
||||
// Marking of active inputs is not properly working as we do not properly
|
||||
// populate AnimNode::m_inputs.
|
||||
//
|
||||
// Here comes an iffy problem: How to mark nodes in a parent blend tree
|
||||
// as active?
|
||||
//
|
||||
// - Simplest would be if the AnimNodes don't distinguish between nodes within
|
||||
// the tree they are contained or in a possible parent (or nested) tree.
|
||||
// - But then how to propagate active connections across multiple layers?
|
||||
// - Therefore probably better to have a blend tree store which sockets are
|
||||
// active and use that within the graph.
|
||||
// - But then: AnimGraphConnection already stores raw AnimNode pointers of the
|
||||
// connected nodes. Still... populating them accross layers could be messy.
|
||||
blend_tree.MarkActiveInputs();
|
||||
blend_tree.UpdateTime(0.f, 0.1f);
|
||||
|
||||
const AnimSamplerNode* walk_node =
|
||||
dynamic_cast<AnimSamplerNode*>(blend_tree.m_nodes[walk_node_index]);
|
||||
const AnimGraphBlendTree* embedded_blend_tree_node =
|
||||
dynamic_cast<AnimGraphBlendTree*>(
|
||||
blend_tree.m_nodes[embedded_blend_tree_node_index]);
|
||||
const SpeedScaleNode* speed_scale_node = dynamic_cast<SpeedScaleNode*>(
|
||||
embedded_blend_tree_node->m_nodes[walk_node_index]);
|
||||
|
||||
blend_tree.StartUpdateTick();
|
||||
blend_tree.MarkActiveInputs(std::vector<AnimGraphConnection>());
|
||||
REQUIRE(embedded_blend_tree_node->m_state == AnimNodeEvalState::Activated);
|
||||
REQUIRE(speed_scale_node->m_state == AnimNodeEvalState::Activated);
|
||||
REQUIRE(walk_node->m_state == AnimNodeEvalState::Activated);
|
||||
|
||||
float time_last = 0.f;
|
||||
float dt = 0.1f;
|
||||
blend_tree.UpdateTime(time_last, time_last + dt);
|
||||
CHECK(embedded_blend_tree_node->m_state == AnimNodeEvalState::TimeUpdated);
|
||||
CHECK(speed_scale_node->m_state == AnimNodeEvalState::TimeUpdated);
|
||||
CHECK(walk_node->m_state == AnimNodeEvalState::TimeUpdated);
|
||||
|
||||
CHECK_THAT(
|
||||
walk_node->m_time_last,
|
||||
Catch::Matchers::WithinAbs(time_last, 0.001));
|
||||
CHECK_THAT(
|
||||
walk_node->m_time_now,
|
||||
Catch::Matchers::WithinAbs(
|
||||
time_last + dt * (*speed_scale_node->i_speed_scale),
|
||||
0.001));
|
||||
|
||||
blend_tree.Evaluate(graph_context);
|
||||
|
||||
WHEN("Updating the time a second time") {
|
||||
// Perform another update
|
||||
time_last = time_last + dt;
|
||||
dt = 0.3f;
|
||||
blend_tree.StartUpdateTick();
|
||||
blend_tree.MarkActiveInputs(std::vector<AnimGraphConnection>());
|
||||
blend_tree.UpdateTime(time_last, time_last + dt);
|
||||
CHECK(embedded_blend_tree_node->m_state == AnimNodeEvalState::TimeUpdated);
|
||||
CHECK(speed_scale_node->m_state == AnimNodeEvalState::TimeUpdated);
|
||||
CHECK(walk_node->m_state == AnimNodeEvalState::TimeUpdated);
|
||||
|
||||
CHECK_THAT(
|
||||
walk_node->m_time_last,
|
||||
Catch::Matchers::WithinAbs(
|
||||
time_last * (*speed_scale_node->i_speed_scale),
|
||||
0.001));
|
||||
CHECK_THAT(
|
||||
walk_node->m_time_now,
|
||||
Catch::Matchers::WithinAbs(
|
||||
(time_last + dt) * (*speed_scale_node->i_speed_scale),
|
||||
0.001));
|
||||
}
|
||||
|
||||
graph_context.freeAnimations();
|
||||
}
|
||||
Reference in New Issue
Block a user