Reduced connection data block size.

Previously we allocated a block for each connection. However when an output is reused by multiple connections this lead to duplicates. It also obfuscated which block is actually being used.
RefactorUnifiedBlendTreeStateMachineHandling
Martin Felis 2024-04-08 21:52:03 +02:00
parent 9f9ac60f9c
commit 2d5337ed1d
2 changed files with 59 additions and 25 deletions

View File

@ -496,10 +496,12 @@ void AnimGraphResource::CreateBlendTreeInstance(
result.m_name = m_name;
NodeSocketDataOffsetMap node_offset_map;
CreateBlendTreeRuntimeNodeInstances(result);
PrepareBlendTreeIOData(result);
PrepareBlendTreeIOData(result, node_offset_map);
SetRuntimeNodeProperties(result);
CreateBlendTreeConnectionInstances(result);
CreateBlendTreeConnectionInstances(result, node_offset_map);
result.UpdateOrderedNodes();
result.ResetNodeStates();
@ -537,7 +539,8 @@ void AnimGraphResource::CreateBlendTreeRuntimeNodeInstances(
}
void AnimGraphResource::PrepareBlendTreeIOData(
AnimGraphBlendTree& instance) const {
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const {
instance.m_node_descriptor =
AnimNodeDescriptorFactory("BlendTree", instance.m_nodes[0]);
@ -590,15 +593,23 @@ void AnimGraphResource::PrepareBlendTreeIOData(
output_block_offset += sizeof(void*);
}
// connections: make source and target sockets point to the same address in the connection data storage.
// TODO: instead of every connection, only create data blocks for the source sockets and make sure every source socket gets allocated once.
//
// connecton data storage
//
size_t connection_data_storage_size = 0;
for (const auto& connection : m_blend_tree_resource.m_connections) {
const AnimNodeResource* source_node =
m_blend_tree_resource.m_nodes[connection.source_node_index];
Socket* source_socket = source_node->m_socket_accessor->GetOutputSocket(
connection.source_socket_name.c_str());
connection_data_storage_size += source_socket->m_type_size;
NodeSocketPair source_socket_pair{source_node, source_socket->m_name};
if (node_offset_map.find(source_socket_pair) == node_offset_map.end()) {
node_offset_map.insert(
{source_socket_pair, connection_data_storage_size});
connection_data_storage_size += source_socket->m_type_size;
}
}
if (connection_data_storage_size > 0) {
@ -608,7 +619,8 @@ void AnimGraphResource::PrepareBlendTreeIOData(
}
void AnimGraphResource::CreateBlendTreeConnectionInstances(
AnimGraphBlendTree& instance) const {
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const {
std::vector<NodeDescriptorBase*> instance_node_descriptors(
m_blend_tree_resource.m_nodes.size(),
nullptr);
@ -630,7 +642,6 @@ void AnimGraphResource::CreateBlendTreeConnectionInstances(
instance_node_descriptors[1]->m_outputs =
instance.m_node_descriptor->m_outputs;
size_t connection_data_offset = 0;
for (const auto& connection : m_blend_tree_resource.m_connections) {
NodeDescriptorBase* source_node_descriptor =
instance_node_descriptors[connection.source_node_index];
@ -729,32 +740,48 @@ void AnimGraphResource::CreateBlendTreeConnectionInstances(
instance_connection.m_target_socket_name = target_socket->m_name;
instance_connection.m_socket = *target_socket;
size_t socket_data_offset = 0;
if (connection.source_node_index == 1) {
instance_connection.m_socket = *target_socket;
} else if (connection.target_node_index == 0) {
instance_connection.m_socket = *source_socket;
} else {
if (connection.target_node_index == 0) {
instance_connection.m_socket = *source_socket;
}
NodeSocketPair node_socket_pair{
m_blend_tree_resource.m_nodes[connection.source_node_index],
source_socket->m_name};
NodeSocketDataOffsetMap::const_iterator socket_data_offset_iter =
node_offset_map.find(node_socket_pair);
if (socket_data_offset_iter != node_offset_map.end()) {
socket_data_offset = socket_data_offset_iter->second;
} else {
std::cerr << "Error: could not find data offset for node '"
<< source_node->m_name << "' and socket '"
<< source_socket->m_name << "'." << std::endl;
assert(false);
abort();
}
*target_socket->m_reference.ptr_ptr =
&instance.m_connection_data_storage[connection_data_offset];
&instance.m_connection_data_storage[socket_data_offset];
*source_socket->m_reference.ptr_ptr =
&instance.m_connection_data_storage[connection_data_offset];
&instance.m_connection_data_storage[socket_data_offset];
if (source_socket->m_type == SocketType::SocketTypeAnimation) {
instance.m_animdata_blocks.push_back(
(AnimData*)(&instance
.m_connection_data_storage[socket_data_offset]));
}
}
instance.m_node_input_connections[connection.target_node_index].push_back(
instance_connection);
instance.m_node_output_connections[connection.source_node_index].push_back(
instance_connection);
*instance_connection.m_socket.m_reference.ptr_ptr =
&instance.m_connection_data_storage[connection_data_offset];
if (source_socket->m_type == SocketType::SocketTypeAnimation) {
instance.m_animdata_blocks.push_back(
(AnimData*)(&instance
.m_connection_data_storage[connection_data_offset]));
}
connection_data_offset += source_socket->m_type_size;
}
//

View File

@ -161,6 +161,9 @@ struct AnimGraphResource : AnimNodeResource {
std::string m_graph_type_name;
BlendTreeResource m_blend_tree_resource;
typedef std::pair<const AnimNodeResource*, std::string> NodeSocketPair;
typedef std::map<NodeSocketPair, int> NodeSocketDataOffsetMap;
StateMachineResource m_state_machine_resource;
void Clear() { m_blend_tree_resource.Reset(); }
@ -174,8 +177,12 @@ struct AnimGraphResource : AnimNodeResource {
// BlendTree
bool SaveBlendTreeResourceToFile(const char* filename) const;
void CreateBlendTreeRuntimeNodeInstances(AnimGraphBlendTree& result) const;
void PrepareBlendTreeIOData(AnimGraphBlendTree& instance) const;
void CreateBlendTreeConnectionInstances(AnimGraphBlendTree& instance) const;
void PrepareBlendTreeIOData(
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const;
void CreateBlendTreeConnectionInstances(
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const;
void SetRuntimeNodeProperties(AnimGraphBlendTree& result) const;
bool SaveStateMachineResourceToFile(const char* filename) const;