Refactored anim graph data usage and evaluation.
- Refactored NodeSocketAccessor to NodeDescriptor. - Connections are wired up during AnimGraph instantiation. - Output and input sockets point to the same memory location. - No re-wiring needed during evaluation. - AnimGraph are pre-allocated (refactoring for less memory usage postponed). - Evaluation of AnimGraph now possible from the editor.
This commit is contained in:
@@ -19,13 +19,13 @@ struct AnimGraph {
|
||||
std::vector<std::vector<AnimGraphConnection> > m_node_input_connections;
|
||||
std::vector<std::vector<AnimGraphConnection> > m_node_output_connections;
|
||||
std::vector<AnimData*> m_animdata_blocks;
|
||||
NodeDescriptorBase* m_socket_accessor;
|
||||
NodeDescriptorBase* m_node_descriptor;
|
||||
char* m_input_buffer = nullptr;
|
||||
char* m_output_buffer = nullptr;
|
||||
char* m_connection_data_storage = nullptr;
|
||||
|
||||
std::vector<Socket>& getGraphOutputs() { return m_socket_accessor->m_inputs; }
|
||||
std::vector<Socket>& getGraphInputs() { return m_socket_accessor->m_outputs; }
|
||||
std::vector<Socket>& getGraphOutputs() { return m_node_descriptor->m_inputs; }
|
||||
std::vector<Socket>& getGraphInputs() { return m_node_descriptor->m_outputs; }
|
||||
|
||||
AnimDataAllocator m_anim_data_allocator;
|
||||
|
||||
@@ -50,7 +50,7 @@ struct AnimGraph {
|
||||
}
|
||||
m_nodes.clear();
|
||||
|
||||
delete m_socket_accessor;
|
||||
delete m_node_descriptor;
|
||||
}
|
||||
|
||||
void updateOrderedNodes();
|
||||
@@ -60,11 +60,6 @@ struct AnimGraph {
|
||||
return node->m_state != AnimNodeEvalState::Deactivated;
|
||||
}
|
||||
|
||||
void evalInputNode();
|
||||
void prepareNodeEval(AnimGraphContext& graph_context, size_t node_index);
|
||||
void finishNodeEval(size_t node_index);
|
||||
void evalOutputNode();
|
||||
|
||||
void evalSyncTracks();
|
||||
void updateTime(float dt);
|
||||
void evaluate(AnimGraphContext& context);
|
||||
@@ -82,6 +77,91 @@ struct AnimGraph {
|
||||
const Socket* getInputSocket(const std::string& name) const;
|
||||
const Socket* getOutputSocket(const std::string& name) const;
|
||||
|
||||
/** Sets the address that is used for the specified AnimGraph input Socket.
|
||||
*
|
||||
* @tparam T Type of the Socket.
|
||||
* @param name Name of the Socket.
|
||||
* @param value_ptr Pointer where the input is fetched during evaluation.
|
||||
*/
|
||||
template <typename T>
|
||||
void SetInput(const char* name, T* value_ptr) {
|
||||
m_node_descriptor->SetOutput(name, value_ptr);
|
||||
|
||||
for (int i = 0; i < m_node_output_connections[1].size(); i++) {
|
||||
const AnimGraphConnection& graph_input_connection =
|
||||
m_node_output_connections[1][i];
|
||||
|
||||
if (graph_input_connection.m_source_socket.m_name == name) {
|
||||
*graph_input_connection.m_target_socket.m_reference.ptr_ptr = value_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the address that is used for the specified AnimGraph output Socket.
|
||||
*
|
||||
* @tparam T Type of the Socket.
|
||||
* @param name Name of the Socket.
|
||||
* @param value_ptr Pointer where the graph output output is written to at the end of evaluation.
|
||||
*/
|
||||
template <typename T>
|
||||
void SetOutput(const char* name, T* value_ptr) {
|
||||
m_node_descriptor->SetInput(name, value_ptr);
|
||||
|
||||
for (int i = 0; i < m_node_input_connections[0].size(); i++) {
|
||||
const AnimGraphConnection& graph_output_connection =
|
||||
m_node_input_connections[0][i];
|
||||
|
||||
if (graph_output_connection.m_target_socket.m_name == name) {
|
||||
if (graph_output_connection.m_source_node == m_nodes[1]
|
||||
&& graph_output_connection.m_target_node == m_nodes[0]) {
|
||||
std::cerr << "Error: cannot set output for direct graph input to graph "
|
||||
"output connections. Use GetOutptPtr for output instead!"
|
||||
<< std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
*graph_output_connection.m_source_socket.m_reference.ptr_ptr =
|
||||
value_ptr;
|
||||
|
||||
// Make sure all other output connections of this pin use the same output pointer
|
||||
int source_node_index = getAnimNodeIndex(graph_output_connection.m_source_node);
|
||||
for (int j = 0; j < m_node_output_connections[source_node_index].size(); j++) {
|
||||
const AnimGraphConnection& source_output_connection = m_node_output_connections[source_node_index][j];
|
||||
if (source_output_connection.m_target_node == m_nodes[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (source_output_connection.m_source_socket.m_name == graph_output_connection.m_source_socket.m_name) {
|
||||
*source_output_connection.m_target_socket.m_reference.ptr_ptr = value_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the address that is used for the specified AnimGraph output Socket.
|
||||
*
|
||||
* This function is needed for connections that directly connect an AnimGraph
|
||||
* input Socket to an output Socket of the same AnimGraph.
|
||||
*
|
||||
* @tparam T Type of the Socket.
|
||||
* @param name Name of the Socket.
|
||||
* @return Address that is used for the specified AnimGraph output Socket.
|
||||
*/
|
||||
template <typename T>
|
||||
T* GetOutputPtr(const char* name) {
|
||||
for (int i = 0; i < m_node_input_connections[0].size(); i++) {
|
||||
const AnimGraphConnection& graph_output_connection =
|
||||
m_node_input_connections[0][i];
|
||||
if (graph_output_connection.m_target_socket.m_name == name) {
|
||||
return static_cast<float*>(*graph_output_connection.m_source_socket.m_reference.ptr_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* getInputPtr(const std::string& name) const {
|
||||
const Socket* input_socket = getInputSocket(name);
|
||||
if (input_socket != nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user