Started working on graph initialization in ATP Editor.
parent
a1931185d8
commit
e38c0b4934
|
@ -7,6 +7,8 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
bool AnimGraph::init(AnimGraphContext& context) {
|
bool AnimGraph::init(AnimGraphContext& context) {
|
||||||
|
context.m_graph = this;
|
||||||
|
|
||||||
for (size_t i = 2; i < m_nodes.size(); i++) {
|
for (size_t i = 2; i < m_nodes.size(); i++) {
|
||||||
if (!m_nodes[i]->Init(context)) {
|
if (!m_nodes[i]->Init(context)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -27,14 +27,20 @@ struct AnimGraph {
|
||||||
|
|
||||||
AnimDataAllocator m_anim_data_allocator;
|
AnimDataAllocator m_anim_data_allocator;
|
||||||
|
|
||||||
~AnimGraph() {
|
~AnimGraph() { dealloc(); }
|
||||||
std::vector<AnimGraphConnection>& graph_outputs = m_node_input_connections[0];
|
|
||||||
|
bool init(AnimGraphContext& context);
|
||||||
|
void dealloc() {
|
||||||
|
if (m_node_input_connections.size() > 0) {
|
||||||
|
std::vector<AnimGraphConnection>& graph_outputs =
|
||||||
|
m_node_input_connections[0];
|
||||||
|
|
||||||
for (size_t i = 0, n = graph_outputs.size(); i < n; i++) {
|
for (size_t i = 0, n = graph_outputs.size(); i < n; i++) {
|
||||||
AnimGraphConnection& connection = graph_outputs[i];
|
AnimGraphConnection& connection = graph_outputs[i];
|
||||||
if (connection.m_target_socket.m_type == SocketType::SocketTypeAnimation) {
|
if (connection.m_target_socket.m_type
|
||||||
AnimData* graph_anim_output =
|
== SocketType::SocketTypeAnimation) {
|
||||||
static_cast<AnimData*>(connection.m_target_socket.m_reference.ptr);
|
AnimData* graph_anim_output = static_cast<AnimData*>(
|
||||||
|
connection.m_target_socket.m_reference.ptr);
|
||||||
assert(graph_anim_output != nullptr);
|
assert(graph_anim_output != nullptr);
|
||||||
|
|
||||||
// we have to explicitly call the destructor as the AnimData* was
|
// we have to explicitly call the destructor as the AnimData* was
|
||||||
|
@ -42,6 +48,7 @@ struct AnimGraph {
|
||||||
graph_anim_output->m_local_matrices.vector::~vector();
|
graph_anim_output->m_local_matrices.vector::~vector();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete[] m_input_buffer;
|
delete[] m_input_buffer;
|
||||||
delete[] m_output_buffer;
|
delete[] m_output_buffer;
|
||||||
|
@ -53,8 +60,6 @@ struct AnimGraph {
|
||||||
delete m_socket_accessor;
|
delete m_socket_accessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(AnimGraphContext& context);
|
|
||||||
|
|
||||||
void updateOrderedNodes();
|
void updateOrderedNodes();
|
||||||
void updateOrderedNodesRecursive(int node_index);
|
void updateOrderedNodesRecursive(int node_index);
|
||||||
void markActiveNodes();
|
void markActiveNodes();
|
||||||
|
@ -70,7 +75,7 @@ struct AnimGraph {
|
||||||
void evalSyncTracks();
|
void evalSyncTracks();
|
||||||
void updateTime(float dt);
|
void updateTime(float dt);
|
||||||
void evaluate(AnimGraphContext& context);
|
void evaluate(AnimGraphContext& context);
|
||||||
void reset() {
|
void resetNodeStates() {
|
||||||
for (size_t i = 0, n = m_nodes.size(); i < n; i++) {
|
for (size_t i = 0, n = m_nodes.size(); i < n; i++) {
|
||||||
m_nodes[i]->m_time_now = 0.f;
|
m_nodes[i]->m_time_now = 0.f;
|
||||||
m_nodes[i]->m_time_last = 0.f;
|
m_nodes[i]->m_time_last = 0.f;
|
||||||
|
@ -102,7 +107,6 @@ struct AnimGraph {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int getNodeEvalOrderIndex(const AnimNode* node) {
|
int getNodeEvalOrderIndex(const AnimNode* node) {
|
||||||
for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) {
|
for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) {
|
||||||
if (m_eval_ordered_nodes[i] == node) {
|
if (m_eval_ordered_nodes[i] == node) {
|
||||||
|
@ -112,12 +116,13 @@ struct AnimGraph {
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const AnimNode* getAnimNodeForInput (
|
const AnimNode* getAnimNodeForInput(
|
||||||
size_t node_index,
|
size_t node_index,
|
||||||
const std::string& input_name) const {
|
const std::string& input_name) const {
|
||||||
assert(node_index < m_nodes.size());
|
assert(node_index < m_nodes.size());
|
||||||
|
|
||||||
const std::vector<AnimGraphConnection>& input_connection = m_node_input_connections[node_index];
|
const std::vector<AnimGraphConnection>& input_connection =
|
||||||
|
m_node_input_connections[node_index];
|
||||||
for (size_t i = 0, n = input_connection.size(); i < n; i++) {
|
for (size_t i = 0, n = input_connection.size(); i < n; i++) {
|
||||||
if (input_connection[i].m_target_socket.m_name == input_name) {
|
if (input_connection[i].m_target_socket.m_name == input_name) {
|
||||||
return input_connection[i].m_source_node;
|
return input_connection[i].m_source_node;
|
||||||
|
@ -137,7 +142,7 @@ struct AnimGraph {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getAnimNodeIndex (AnimNode* node) {
|
size_t getAnimNodeIndex(AnimNode* node) {
|
||||||
for (size_t i = 0; i < m_nodes.size(); i++) {
|
for (size_t i = 0; i < m_nodes.size(); i++) {
|
||||||
if (m_nodes[i] == node) {
|
if (m_nodes[i] == node) {
|
||||||
return i;
|
return i;
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include "SyncTrack.h"
|
#include "SyncTrack.h"
|
||||||
#include "ozz/animation/runtime/animation.h"
|
#include "ozz/animation/runtime/animation.h"
|
||||||
|
@ -76,16 +76,15 @@ struct AnimDataAllocator {
|
||||||
|
|
||||||
void free(AnimData* anim_data) {
|
void free(AnimData* anim_data) {
|
||||||
#ifdef ANIM_DATA_ALLOCATOR_DEBUG
|
#ifdef ANIM_DATA_ALLOCATOR_DEBUG
|
||||||
std::cout << "Storing buffer with size " << anim_data->m_local_matrices.size()
|
std::cout << "Storing buffer with size "
|
||||||
<< " " << anim_data << std::endl;
|
<< anim_data->m_local_matrices.size() << " " << anim_data
|
||||||
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_anim_data_list.push_front(anim_data);
|
m_anim_data_list.push_front(anim_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() {
|
size_t size() { return m_anim_data_list.size(); }
|
||||||
return m_anim_data_list.size();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnimGraphContext {
|
struct AnimGraphContext {
|
||||||
|
@ -134,7 +133,7 @@ struct Socket {
|
||||||
float float_value;
|
float float_value;
|
||||||
float vec3[3];
|
float vec3[3];
|
||||||
float quat[4];
|
float quat[4];
|
||||||
char str[cSocketStringValueMaxLength];
|
std::string* string_ptr;
|
||||||
};
|
};
|
||||||
SocketValue m_value = {0};
|
SocketValue m_value = {0};
|
||||||
union SocketReference {
|
union SocketReference {
|
||||||
|
@ -265,6 +264,9 @@ struct NodeSocketAccessorBase {
|
||||||
socket->m_type = SocketType::SocketTypeAnimation;
|
socket->m_type = SocketType::SocketTypeAnimation;
|
||||||
} else if constexpr (std::is_same<T, std::string>::value) {
|
} else if constexpr (std::is_same<T, std::string>::value) {
|
||||||
socket->m_type = SocketType::SocketTypeString;
|
socket->m_type = SocketType::SocketTypeString;
|
||||||
|
socket->m_value.string_ptr = value_ptr;
|
||||||
|
socket->m_reference.ptr = value_ptr;
|
||||||
|
return true;
|
||||||
} else if constexpr (std::is_same<T, float*>::value) {
|
} else if constexpr (std::is_same<T, float*>::value) {
|
||||||
socket->m_type = SocketType::SocketTypeFloat;
|
socket->m_type = SocketType::SocketTypeFloat;
|
||||||
} else if constexpr (std::is_same<T, bool*>::value) {
|
} else if constexpr (std::is_same<T, bool*>::value) {
|
||||||
|
@ -381,6 +383,13 @@ inline void NodeSocketAccessorBase::SetSocketReferenceValue<const Quat&>(
|
||||||
static_cast<float*>(socket->m_reference.ptr)[3] = value[3];
|
static_cast<float*>(socket->m_reference.ptr)[3] = value[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const std::string*>(
|
||||||
|
Socket* socket,
|
||||||
|
const std::string* value) {
|
||||||
|
socket->m_value.string_ptr = const_cast<std::string*>(value);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const std::string&>(
|
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const std::string&>(
|
||||||
Socket* socket,
|
Socket* socket,
|
||||||
|
@ -433,20 +442,17 @@ inline void NodeSocketAccessorBase::SetSocketValue<const Quat&>(
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline void NodeSocketAccessorBase::SetSocketValue<const std::string&>(
|
inline void NodeSocketAccessorBase::SetSocketValue<std::string>(
|
||||||
Socket* socket,
|
Socket* socket,
|
||||||
const std::string& value) {
|
std::string value) {
|
||||||
constexpr size_t string_max_length = sizeof(socket->m_value.str) - 1;
|
*socket->m_value.string_ptr = value;
|
||||||
strncpy(socket->m_value.str, value.data(), string_max_length);
|
|
||||||
socket->m_value.str
|
|
||||||
[value.size() > string_max_length ? string_max_length : value.size()] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline void NodeSocketAccessorBase::SetSocketValue<const char*>(
|
inline void NodeSocketAccessorBase::SetSocketValue<const char*>(
|
||||||
Socket* socket,
|
Socket* socket,
|
||||||
const char* value) {
|
const char* value) {
|
||||||
SetSocketValue<const std::string&>(socket, value);
|
SetSocketValue<std::string>(socket, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "imnodes.h"
|
#include "imnodes.h"
|
||||||
#include "misc/cpp/imgui_stdlib.h"
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
|
|
||||||
|
static AnimGraphResource sGraphGresource = AnimGraphResource();
|
||||||
|
|
||||||
ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) {
|
ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) {
|
||||||
switch (socket_type) {
|
switch (socket_type) {
|
||||||
case SocketType::SocketTypeAnimation:
|
case SocketType::SocketTypeAnimation:
|
||||||
|
@ -54,7 +56,7 @@ void RemoveConnectionsForSocket(
|
||||||
// AnimGraphConnectionResource& connection = *iter;
|
// AnimGraphConnectionResource& connection = *iter;
|
||||||
// if (connection.m_source_node == &node_resource
|
// if (connection.m_source_node == &node_resource
|
||||||
// && connection.m_source_socket == &socket) {
|
// && connection.m_source_socket == &socket) {
|
||||||
// iter = graph_resource.m_connections.erase(iter);
|
// iter = sGraphGresource.m_connections.erase(iter);
|
||||||
// } else {
|
// } else {
|
||||||
// iter++;
|
// iter++;
|
||||||
// }
|
// }
|
||||||
|
@ -91,19 +93,13 @@ void AnimGraphEditorRenderSidebar(
|
||||||
property.m_name.c_str(),
|
property.m_name.c_str(),
|
||||||
reinterpret_cast<bool*>(property.m_reference.ptr));
|
reinterpret_cast<bool*>(property.m_reference.ptr));
|
||||||
} else if (property.m_type == SocketType::SocketTypeString) {
|
} else if (property.m_type == SocketType::SocketTypeString) {
|
||||||
std::string* property_string =
|
char string_buf[1024];
|
||||||
reinterpret_cast<std::string*>(property.m_reference.ptr);
|
memcpy (string_buf, property.m_value.string_ptr->c_str(), property.m_value.string_ptr->size() + 1);
|
||||||
char string_buf[256];
|
|
||||||
memset(string_buf, 0, sizeof(string_buf));
|
|
||||||
strncpy(
|
|
||||||
string_buf,
|
|
||||||
property_string->c_str(),
|
|
||||||
std::min(property_string->size(), sizeof(string_buf)));
|
|
||||||
if (ImGui::InputText(
|
if (ImGui::InputText(
|
||||||
property.m_name.c_str(),
|
property.m_name.c_str(),
|
||||||
string_buf,
|
string_buf,
|
||||||
sizeof(string_buf))) {
|
sizeof(string_buf))) {
|
||||||
(*property_string) = string_buf;
|
*property.m_value.string_ptr = string_buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,33 +148,31 @@ void AnimGraphEditorRenderSidebar(
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimGraphEditorUpdate() {
|
void AnimGraphEditorUpdate() {
|
||||||
static AnimGraphResource graph_resource = AnimGraphResource();
|
|
||||||
|
|
||||||
ImGui::BeginMenuBar();
|
ImGui::BeginMenuBar();
|
||||||
if (ImGui::Button("Save")) {
|
if (ImGui::Button("Save")) {
|
||||||
graph_resource.saveToFile("editor_graph.json");
|
sGraphGresource.saveToFile("editor_graph.json");
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Load")) {
|
if (ImGui::Button("Load")) {
|
||||||
graph_resource.loadFromFile("editor_graph.json");
|
sGraphGresource.loadFromFile("editor_graph.json");
|
||||||
|
|
||||||
for (size_t i = 0, n = graph_resource.m_nodes.size(); i < n; i++) {
|
for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) {
|
||||||
const AnimNodeResource& node_resource = graph_resource.m_nodes[i];
|
const AnimNodeResource& node_resource = sGraphGresource.m_nodes[i];
|
||||||
ImNodes::SetNodeGridSpacePos(
|
ImNodes::SetNodeGridSpacePos(
|
||||||
i,
|
i,
|
||||||
ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
|
ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Clear")) {
|
if (ImGui::Button("Clear")) {
|
||||||
graph_resource.clear();
|
sGraphGresource.clear();
|
||||||
}
|
}
|
||||||
char graph_name_buffer[256];
|
char graph_name_buffer[256];
|
||||||
memset(graph_name_buffer, 0, sizeof(graph_name_buffer));
|
memset(graph_name_buffer, 0, sizeof(graph_name_buffer));
|
||||||
strncpy(
|
strncpy(
|
||||||
graph_name_buffer,
|
graph_name_buffer,
|
||||||
graph_resource.m_name.c_str(),
|
sGraphGresource.m_name.c_str(),
|
||||||
sizeof(graph_name_buffer));
|
sizeof(graph_name_buffer));
|
||||||
if (ImGui::InputText("Name", graph_name_buffer, sizeof(graph_name_buffer))) {
|
if (ImGui::InputText("Name", graph_name_buffer, sizeof(graph_name_buffer))) {
|
||||||
graph_resource.m_name = graph_name_buffer;
|
sGraphGresource.m_name = graph_name_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
|
@ -228,9 +222,9 @@ void AnimGraphEditorUpdate() {
|
||||||
if (node_type_name != "") {
|
if (node_type_name != "") {
|
||||||
AnimNodeResource node_resource =
|
AnimNodeResource node_resource =
|
||||||
AnimNodeResourceFactory(node_type_name);
|
AnimNodeResourceFactory(node_type_name);
|
||||||
size_t node_id = graph_resource.m_nodes.size();
|
size_t node_id = sGraphGresource.m_nodes.size();
|
||||||
ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos());
|
ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos());
|
||||||
graph_resource.m_nodes.push_back(node_resource);
|
sGraphGresource.m_nodes.push_back(node_resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
|
@ -239,17 +233,17 @@ void AnimGraphEditorUpdate() {
|
||||||
ImGui::PopStyleVar(ImGuiStyleVar_WindowPadding);
|
ImGui::PopStyleVar(ImGuiStyleVar_WindowPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0, n = graph_resource.m_nodes.size(); i < n; i++) {
|
for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) {
|
||||||
AnimNodeResource& node_resource = graph_resource.m_nodes[i];
|
AnimNodeResource& node_resource = sGraphGresource.m_nodes[i];
|
||||||
|
|
||||||
ImNodes::BeginNode(i);
|
ImNodes::BeginNode(i);
|
||||||
ImGui::PushItemWidth(110.0f);
|
ImGui::PushItemWidth(110.0f);
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
ImNodes::BeginNodeTitleBar();
|
ImNodes::BeginNodeTitleBar();
|
||||||
if (&node_resource == &graph_resource.getGraphOutputNode()) {
|
if (&node_resource == &sGraphGresource.getGraphOutputNode()) {
|
||||||
ImGui::TextUnformatted("Graph Outputs");
|
ImGui::TextUnformatted("Graph Outputs");
|
||||||
} else if (&node_resource == &graph_resource.getGraphInputNode()) {
|
} else if (&node_resource == &sGraphGresource.getGraphInputNode()) {
|
||||||
ImGui::TextUnformatted("Graph Inputs");
|
ImGui::TextUnformatted("Graph Inputs");
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextUnformatted(node_resource.m_type_name.c_str());
|
ImGui::TextUnformatted(node_resource.m_type_name.c_str());
|
||||||
|
@ -273,7 +267,8 @@ void AnimGraphEditorUpdate() {
|
||||||
socket_color);
|
socket_color);
|
||||||
ImGui::TextUnformatted(socket.m_name.c_str());
|
ImGui::TextUnformatted(socket.m_name.c_str());
|
||||||
|
|
||||||
bool socket_connected = graph_resource.isSocketConnected(node_resource, socket.m_name);
|
bool socket_connected =
|
||||||
|
sGraphGresource.isSocketConnected(node_resource, socket.m_name);
|
||||||
if (!socket_connected &&
|
if (!socket_connected &&
|
||||||
(socket.m_type == SocketType::SocketTypeFloat)) {
|
(socket.m_type == SocketType::SocketTypeFloat)) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -307,7 +302,7 @@ void AnimGraphEditorUpdate() {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (ImGui::Button("+Output")) {
|
if (ImGui::Button("+Output")) {
|
||||||
AnimNodeResource& graph_output_node =
|
AnimNodeResource& graph_output_node =
|
||||||
graph_resource.getGraphOutputNode();
|
sGraphGresource.getGraphOutputNode();
|
||||||
|
|
||||||
static float bla = 0.f;
|
static float bla = 0.f;
|
||||||
std::string socket_name = "Output";
|
std::string socket_name = "Output";
|
||||||
|
@ -319,7 +314,8 @@ void AnimGraphEditorUpdate() {
|
||||||
}
|
}
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
if (ImGui::Button("+Input")) {
|
if (ImGui::Button("+Input")) {
|
||||||
AnimNodeResource& graph_input_node = graph_resource.getGraphInputNode();
|
AnimNodeResource& graph_input_node =
|
||||||
|
sGraphGresource.getGraphInputNode();
|
||||||
|
|
||||||
static float bla = 0.f;
|
static float bla = 0.f;
|
||||||
std::string socket_name = "Input";
|
std::string socket_name = "Input";
|
||||||
|
@ -343,18 +339,18 @@ void AnimGraphEditorUpdate() {
|
||||||
node_resource.m_socket_accessor->UpdateFlags();
|
node_resource.m_socket_accessor->UpdateFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0, n = graph_resource.m_connections.size(); i < n; i++) {
|
for (size_t i = 0, n = sGraphGresource.m_connections.size(); i < n; i++) {
|
||||||
const AnimGraphConnectionResource& connection =
|
const AnimGraphConnectionResource& connection =
|
||||||
graph_resource.m_connections[i];
|
sGraphGresource.m_connections[i];
|
||||||
int start_attr, end_attr;
|
int start_attr, end_attr;
|
||||||
|
|
||||||
const AnimNodeResource& source_node =
|
const AnimNodeResource& source_node =
|
||||||
graph_resource.m_nodes[connection.source_node_index];
|
sGraphGresource.m_nodes[connection.source_node_index];
|
||||||
int source_socket_index = source_node.m_socket_accessor->GetOutputIndex(
|
int source_socket_index = source_node.m_socket_accessor->GetOutputIndex(
|
||||||
connection.source_socket_name);
|
connection.source_socket_name);
|
||||||
|
|
||||||
const AnimNodeResource& target_node =
|
const AnimNodeResource& target_node =
|
||||||
graph_resource.m_nodes[connection.target_node_index];
|
sGraphGresource.m_nodes[connection.target_node_index];
|
||||||
int target_socket_index = target_node.m_socket_accessor->GetInputIndex(
|
int target_socket_index = target_node.m_socket_accessor->GetInputIndex(
|
||||||
connection.target_socket_name);
|
connection.target_socket_name);
|
||||||
|
|
||||||
|
@ -386,24 +382,29 @@ void AnimGraphEditorUpdate() {
|
||||||
|
|
||||||
AnimGraphConnectionResource connection;
|
AnimGraphConnectionResource connection;
|
||||||
connection.source_node_index = node_start_id;
|
connection.source_node_index = node_start_id;
|
||||||
const AnimNodeResource& source_node = graph_resource.m_nodes[node_start_id];
|
const AnimNodeResource& source_node =
|
||||||
|
sGraphGresource.m_nodes[node_start_id];
|
||||||
connection.source_socket_name =
|
connection.source_socket_name =
|
||||||
source_node.m_socket_accessor->m_outputs[node_start_output_index]
|
source_node.m_socket_accessor->m_outputs[node_start_output_index]
|
||||||
.m_name;
|
.m_name;
|
||||||
|
|
||||||
connection.target_node_index = node_end_id;
|
connection.target_node_index = node_end_id;
|
||||||
const AnimNodeResource& target_node = graph_resource.m_nodes[node_end_id];
|
const AnimNodeResource& target_node = sGraphGresource.m_nodes[node_end_id];
|
||||||
connection.target_socket_name =
|
connection.target_socket_name =
|
||||||
target_node.m_socket_accessor->m_inputs[node_end_input_index].m_name;
|
target_node.m_socket_accessor->m_inputs[node_end_input_index].m_name;
|
||||||
|
|
||||||
graph_resource.m_connections.push_back(connection);
|
sGraphGresource.m_connections.push_back(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::IsKeyPressed(ImGuiKey_Delete, false)) {
|
||||||
|
std::cerr << "Delete key!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle link detachements.
|
// Handle link detachements.
|
||||||
int link_id = 0;
|
int link_id = 0;
|
||||||
if (ImNodes::IsLinkDestroyed(&link_id)) {
|
if (ImNodes::IsLinkDestroyed(&link_id)) {
|
||||||
graph_resource.m_connections.erase(
|
sGraphGresource.m_connections.erase(
|
||||||
graph_resource.m_connections.begin() + link_id);
|
sGraphGresource.m_connections.begin() + link_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int selected_nodes[ImNodes::NumSelectedNodes()];
|
int selected_nodes[ImNodes::NumSelectedNodes()];
|
||||||
|
@ -415,12 +416,16 @@ void AnimGraphEditorUpdate() {
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
|
|
||||||
if (ImNodes::NumSelectedNodes() == 1) {
|
if (ImNodes::NumSelectedNodes() == 1) {
|
||||||
if (selected_nodes[0] < graph_resource.m_nodes.size()) {
|
if (selected_nodes[0] < sGraphGresource.m_nodes.size()) {
|
||||||
AnimNodeResource& selected_node =
|
AnimNodeResource& selected_node =
|
||||||
graph_resource.m_nodes[selected_nodes[0]];
|
sGraphGresource.m_nodes[selected_nodes[0]];
|
||||||
AnimGraphEditorRenderSidebar(graph_resource, selected_node);
|
AnimGraphEditorRenderSidebar(sGraphGresource, selected_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Columns(1);
|
ImGui::Columns(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimGraphEditorGetRuntimeGraph(AnimGraph& anim_graph) {
|
||||||
|
sGraphGresource.createInstance(anim_graph);
|
||||||
|
}
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef ANIMTESTBED_ANIMGRAPHEDITOR_H
|
#ifndef ANIMTESTBED_ANIMGRAPHEDITOR_H
|
||||||
#define ANIMTESTBED_ANIMGRAPHEDITOR_H
|
#define ANIMTESTBED_ANIMGRAPHEDITOR_H
|
||||||
|
|
||||||
|
#include "AnimGraph.h"
|
||||||
|
|
||||||
inline int GenerateInputAttributeId(int node_id, int input_index) {
|
inline int GenerateInputAttributeId(int node_id, int input_index) {
|
||||||
return ((input_index + 1) << 14) + node_id;
|
return ((input_index + 1) << 14) + node_id;
|
||||||
}
|
}
|
||||||
|
@ -27,4 +29,6 @@ SplitOutputAttributeId(int attribute_id, int* node_id, int* output_index) {
|
||||||
|
|
||||||
void AnimGraphEditorUpdate();
|
void AnimGraphEditorUpdate();
|
||||||
|
|
||||||
|
void AnimGraphEditorGetRuntimeGraph(AnimGraph& anim_graph);
|
||||||
|
|
||||||
#endif //ANIMTESTBED_ANIMGRAPHEDITOR_H
|
#endif //ANIMTESTBED_ANIMGRAPHEDITOR_H
|
||||||
|
|
|
@ -43,7 +43,7 @@ json sSocketToJson(const Socket& socket) {
|
||||||
result["value"][2] = socket.m_value.quat[2];
|
result["value"][2] = socket.m_value.quat[2];
|
||||||
result["value"][3] = socket.m_value.quat[3];
|
result["value"][3] = socket.m_value.quat[3];
|
||||||
} else if (socket.m_type == SocketType::SocketTypeString) {
|
} else if (socket.m_type == SocketType::SocketTypeString) {
|
||||||
result["value"] = std::string(socket.m_value.str);
|
result["value"] = *socket.m_value.string_ptr;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Invalid socket type '" << static_cast<int>(socket.m_type)
|
std::cerr << "Invalid socket type '" << static_cast<int>(socket.m_type)
|
||||||
<< "'." << std::endl;
|
<< "'." << std::endl;
|
||||||
|
@ -142,17 +142,7 @@ AnimNodeResource sAnimGraphNodeFromJson(const json& json_node) {
|
||||||
property.m_value.quat[2] = json_property["value"][2];
|
property.m_value.quat[2] = json_property["value"][2];
|
||||||
property.m_value.quat[3] = json_property["value"][3];
|
property.m_value.quat[3] = json_property["value"][3];
|
||||||
} else if (property.m_type == SocketType::SocketTypeString) {
|
} else if (property.m_type == SocketType::SocketTypeString) {
|
||||||
std::string value_str = json_property["value"];
|
*(property.m_value.string_ptr) = json_property["value"].get<std::string>();
|
||||||
size_t string_length = value_str.size();
|
|
||||||
constexpr size_t string_max_length = sizeof(property.m_value.str) - 1;
|
|
||||||
if (string_length > string_max_length) {
|
|
||||||
std::cerr << "Warning: string '" << value_str
|
|
||||||
<< "' too long, truncating to " << string_max_length
|
|
||||||
<< " bytes." << std::endl;
|
|
||||||
string_length = string_max_length;
|
|
||||||
}
|
|
||||||
memcpy(property.m_value.str, value_str.data(), string_length);
|
|
||||||
property.m_value.str[string_length] = 0;
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Invalid type for property '" << property.m_name
|
std::cerr << "Invalid type for property '" << property.m_name
|
||||||
<< "'. Cannot parse json to type '"
|
<< "'. Cannot parse json to type '"
|
||||||
|
@ -263,7 +253,7 @@ bool AnimGraphResource::saveToFile(const char* filename) const {
|
||||||
|
|
||||||
std::ofstream output_file;
|
std::ofstream output_file;
|
||||||
output_file.open(filename);
|
output_file.open(filename);
|
||||||
output_file << to_string(result) << std::endl;
|
output_file << result.dump(4, ' ') << std::endl;
|
||||||
output_file.close();
|
output_file.close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -340,18 +330,14 @@ bool AnimGraphResource::loadFromFile(const char* filename) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimGraph AnimGraphResource::createInstance() const {
|
void AnimGraphResource::createInstance(AnimGraph& result) const {
|
||||||
AnimGraph result;
|
|
||||||
|
|
||||||
createRuntimeNodeInstances(result);
|
createRuntimeNodeInstances(result);
|
||||||
prepareGraphIOData(result);
|
prepareGraphIOData(result);
|
||||||
connectRuntimeNodes(result);
|
connectRuntimeNodes(result);
|
||||||
setRuntimeNodeProperties(result);
|
setRuntimeNodeProperties(result);
|
||||||
|
|
||||||
result.updateOrderedNodes();
|
result.updateOrderedNodes();
|
||||||
result.reset();
|
result.resetNodeStates();
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimGraphResource::createRuntimeNodeInstances(AnimGraph& instance) const {
|
void AnimGraphResource::createRuntimeNodeInstances(AnimGraph& instance) const {
|
||||||
|
@ -384,8 +370,11 @@ void AnimGraphResource::prepareGraphIOData(AnimGraph& instance) const {
|
||||||
for (int i = 0; i < graph_inputs.size(); i++) {
|
for (int i = 0; i < graph_inputs.size(); i++) {
|
||||||
input_block_size += sizeof(void*);
|
input_block_size += sizeof(void*);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (input_block_size > 0) {
|
||||||
instance.m_input_buffer = new char[input_block_size];
|
instance.m_input_buffer = new char[input_block_size];
|
||||||
memset(instance.m_input_buffer, 0, input_block_size);
|
memset(instance.m_input_buffer, 0, input_block_size);
|
||||||
|
}
|
||||||
|
|
||||||
int input_block_offset = 0;
|
int input_block_offset = 0;
|
||||||
for (int i = 0; i < graph_inputs.size(); i++) {
|
for (int i = 0; i < graph_inputs.size(); i++) {
|
||||||
|
@ -400,8 +389,11 @@ void AnimGraphResource::prepareGraphIOData(AnimGraph& instance) const {
|
||||||
for (int i = 0; i < graph_outputs.size(); i++) {
|
for (int i = 0; i < graph_outputs.size(); i++) {
|
||||||
output_block_size += graph_outputs[i].m_type_size;
|
output_block_size += graph_outputs[i].m_type_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output_block_size > 0) {
|
||||||
instance.m_output_buffer = new char[output_block_size];
|
instance.m_output_buffer = new char[output_block_size];
|
||||||
memset(instance.m_output_buffer, 0, output_block_size);
|
memset(instance.m_output_buffer, 0, output_block_size);
|
||||||
|
}
|
||||||
|
|
||||||
int output_block_offset = 0;
|
int output_block_offset = 0;
|
||||||
for (int i = 0; i < graph_outputs.size(); i++) {
|
for (int i = 0; i < graph_outputs.size(); i++) {
|
||||||
|
@ -557,9 +549,9 @@ void AnimGraphResource::setRuntimeNodeProperties(AnimGraph& instance) const {
|
||||||
property.m_value.quat);
|
property.m_value.quat);
|
||||||
break;
|
break;
|
||||||
case SocketType::SocketTypeString:
|
case SocketType::SocketTypeString:
|
||||||
node_instance_accessor->SetPropertyReferenceValue(
|
node_instance_accessor->SetPropertyValue(
|
||||||
name,
|
name,
|
||||||
property.m_value.str);
|
*property.m_value.string_ptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Invalid socket type "
|
std::cerr << "Invalid socket type "
|
||||||
|
|
|
@ -140,7 +140,7 @@ struct AnimGraphResource {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimGraph createInstance() const;
|
void createInstance(AnimGraph& result) const;
|
||||||
|
|
||||||
void createRuntimeNodeInstances(AnimGraph& instance) const;
|
void createRuntimeNodeInstances(AnimGraph& instance) const;
|
||||||
void prepareGraphIOData(AnimGraph& instance) const;
|
void prepareGraphIOData(AnimGraph& instance) const;
|
||||||
|
|
32
src/main.cc
32
src/main.cc
|
@ -82,6 +82,7 @@ static struct {
|
||||||
float anim_ratio;
|
float anim_ratio;
|
||||||
bool anim_ratio_ui_override;
|
bool anim_ratio_ui_override;
|
||||||
bool paused;
|
bool paused;
|
||||||
|
bool use_graph = false;
|
||||||
} time;
|
} time;
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
|
@ -311,7 +312,7 @@ int main() {
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_FALSE);
|
glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_SAMPLES, 16);
|
glfwWindowHint(GLFW_SAMPLES, 16);
|
||||||
GLFWwindow* w = glfwCreateWindow(Width, Height, "AnimTestbed", 0, 0);
|
GLFWwindow* w = glfwCreateWindow(Width, Height, "ATP Editor", 0, 0);
|
||||||
glfwMakeContextCurrent(w);
|
glfwMakeContextCurrent(w);
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
|
|
||||||
|
@ -378,9 +379,11 @@ int main() {
|
||||||
|
|
||||||
SkinnedMesh skinned_mesh;
|
SkinnedMesh skinned_mesh;
|
||||||
skinned_mesh_resource.createInstance(skinned_mesh);
|
skinned_mesh_resource.createInstance(skinned_mesh);
|
||||||
|
|
||||||
skinned_mesh.SetCurrentAnimation(0);
|
skinned_mesh.SetCurrentAnimation(0);
|
||||||
|
|
||||||
|
AnimGraph anim_graph;
|
||||||
|
AnimGraphContext anim_graph_context;
|
||||||
|
|
||||||
state.time.factor = 1.0f;
|
state.time.factor = 1.0f;
|
||||||
|
|
||||||
Camera_Init(&state.camera);
|
Camera_Init(&state.camera);
|
||||||
|
@ -611,6 +614,13 @@ int main() {
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Update Runtime Graph")) {
|
||||||
|
anim_graph.dealloc();
|
||||||
|
AnimGraphEditorGetRuntimeGraph(anim_graph);
|
||||||
|
anim_graph_context.m_skeleton = &skinned_mesh.m_skeleton;
|
||||||
|
anim_graph.init(anim_graph_context);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,8 +664,8 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gApplicationConfig.animation_player_widget.visible) {
|
if (gApplicationConfig.animation_player_widget.visible) {
|
||||||
ImGui::SetNextWindowPos(ImVec2(gApplicationConfig.animation_player_widget.position[0], gApplicationConfig.skinned_mesh_widget.position[1]), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowPos(ImVec2(gApplicationConfig.animation_player_widget.position[0], gApplicationConfig.animation_player_widget.position[1]), ImGuiCond_FirstUseEver);
|
||||||
ImGui::SetNextWindowSize(ImVec2(gApplicationConfig.animation_player_widget.size[0], gApplicationConfig.skinned_mesh_widget.size[1]), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2(gApplicationConfig.animation_player_widget.size[0], gApplicationConfig.animation_player_widget.size[1]), ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
ImGui::Begin("Animation Player", &gApplicationConfig.animation_player_widget.visible);
|
ImGui::Begin("Animation Player", &gApplicationConfig.animation_player_widget.visible);
|
||||||
|
|
||||||
|
@ -667,6 +677,13 @@ int main() {
|
||||||
gApplicationConfig.animation_player_widget.size[0] = animation_player_widget_size.x;
|
gApplicationConfig.animation_player_widget.size[0] = animation_player_widget_size.x;
|
||||||
gApplicationConfig.animation_player_widget.size[1] = animation_player_widget_size.y;
|
gApplicationConfig.animation_player_widget.size[1] = animation_player_widget_size.y;
|
||||||
|
|
||||||
|
if (anim_graph.m_nodes.size() > 0) {
|
||||||
|
ImGui::Checkbox("Use Graph", &state.time.use_graph);
|
||||||
|
} else {
|
||||||
|
state.time.use_graph = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.time.use_graph) {
|
||||||
ImGui::Text("Animation");
|
ImGui::Text("Animation");
|
||||||
|
|
||||||
const char* items[255] = {0};
|
const char* items[255] = {0};
|
||||||
|
@ -675,9 +692,14 @@ int main() {
|
||||||
items[i] = skinned_mesh.m_animation_names[i].c_str();
|
items[i] = skinned_mesh.m_animation_names[i].c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Combo("Animation", &selected, items, skinned_mesh.m_animations.size())) {
|
if (ImGui::Combo(
|
||||||
|
"Animation",
|
||||||
|
&selected,
|
||||||
|
items,
|
||||||
|
skinned_mesh.m_animations.size())) {
|
||||||
state.ozz.animation = skinned_mesh.m_animations[selected];
|
state.ozz.animation = skinned_mesh.m_animations[selected];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state.time.paused) {
|
if (state.time.paused) {
|
||||||
if (ImGui::Button("Play")) {
|
if (ImGui::Button("Play")) {
|
||||||
|
|
|
@ -190,8 +190,8 @@ TEST_CASE_METHOD(
|
||||||
graph_context.m_animation_map["trans_y"] = animation_translate_y.get();
|
graph_context.m_animation_map["trans_y"] = animation_translate_y.get();
|
||||||
|
|
||||||
// Instantiate graph
|
// Instantiate graph
|
||||||
AnimGraph graph = graph_resource.createInstance();
|
AnimGraph graph;
|
||||||
graph_context.m_graph = &graph;
|
graph_resource.createInstance(graph);
|
||||||
graph.init(graph_context);
|
graph.init(graph_context);
|
||||||
|
|
||||||
// Get runtime graph inputs and outputs
|
// Get runtime graph inputs and outputs
|
||||||
|
|
|
@ -74,9 +74,9 @@ TEST_CASE("BasicGraph", "[AnimGraphResource]") {
|
||||||
AnimGraphResource graph_resource_loaded;
|
AnimGraphResource graph_resource_loaded;
|
||||||
graph_resource_loaded.loadFromFile("WalkGraph.animgraph.json");
|
graph_resource_loaded.loadFromFile("WalkGraph.animgraph.json");
|
||||||
|
|
||||||
AnimGraph graph = graph_resource_loaded.createInstance();
|
AnimGraph graph;
|
||||||
|
graph_resource_loaded.createInstance(graph);
|
||||||
AnimGraphContext graph_context;
|
AnimGraphContext graph_context;
|
||||||
graph_context.m_graph = &graph;
|
|
||||||
|
|
||||||
ozz::animation::Skeleton skeleton;
|
ozz::animation::Skeleton skeleton;
|
||||||
REQUIRE(load_skeleton(skeleton, "data/skeleton.ozz"));
|
REQUIRE(load_skeleton(skeleton, "data/skeleton.ozz"));
|
||||||
|
@ -283,7 +283,8 @@ TEST_CASE("ResourceSaveLoadMathGraphInputs", "[AnimGraphResource]") {
|
||||||
!= nullptr);
|
!= nullptr);
|
||||||
|
|
||||||
WHEN("Instantiating an AnimGraph") {
|
WHEN("Instantiating an AnimGraph") {
|
||||||
AnimGraph anim_graph = graph_resource_loaded.createInstance();
|
AnimGraph anim_graph;
|
||||||
|
graph_resource_loaded.createInstance(anim_graph);
|
||||||
|
|
||||||
REQUIRE(anim_graph.getInputSocket("GraphFloatInput") != nullptr);
|
REQUIRE(anim_graph.getInputSocket("GraphFloatInput") != nullptr);
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
|
@ -418,7 +419,8 @@ TEST_CASE("SimpleMathEvaluations", "[AnimGraphResource]") {
|
||||||
graph_resource_loaded.m_nodes[1];
|
graph_resource_loaded.m_nodes[1];
|
||||||
|
|
||||||
WHEN("Instantiating an AnimGraph") {
|
WHEN("Instantiating an AnimGraph") {
|
||||||
AnimGraph anim_graph = graph_resource_loaded.createInstance();
|
AnimGraph anim_graph;
|
||||||
|
graph_resource_loaded.createInstance(anim_graph);
|
||||||
|
|
||||||
REQUIRE(anim_graph.getInputSocket("GraphFloatInput") != nullptr);
|
REQUIRE(anim_graph.getInputSocket("GraphFloatInput") != nullptr);
|
||||||
REQUIRE(
|
REQUIRE(
|
||||||
|
@ -495,12 +497,12 @@ TEST_CASE("SimpleMathEvaluations", "[AnimGraphResource]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
AnimGraphResource graph_resource;
|
AnimGraphResource sGraphGresource;
|
||||||
|
|
||||||
graph_resource.clear();
|
sGraphGresource.clear();
|
||||||
graph_resource.m_name = "TestGraphInputOutputConnectivity";
|
sGraphGresource.m_name = "TestGraphInputOutputConnectivity";
|
||||||
|
|
||||||
AnimNodeResource& graph_output_node = graph_resource.m_nodes[0];
|
AnimNodeResource& graph_output_node = sGraphGresource.m_nodes[0];
|
||||||
graph_output_node.m_socket_accessor->RegisterInput<float>(
|
graph_output_node.m_socket_accessor->RegisterInput<float>(
|
||||||
"GraphFloatOutput",
|
"GraphFloatOutput",
|
||||||
nullptr);
|
nullptr);
|
||||||
|
@ -508,7 +510,7 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
"GraphAnimOutput",
|
"GraphAnimOutput",
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
AnimNodeResource& graph_input_node = graph_resource.m_nodes[1];
|
AnimNodeResource& graph_input_node = sGraphGresource.m_nodes[1];
|
||||||
graph_input_node.m_socket_accessor->RegisterOutput<float>(
|
graph_input_node.m_socket_accessor->RegisterOutput<float>(
|
||||||
"GraphFloatInput",
|
"GraphFloatInput",
|
||||||
nullptr);
|
nullptr);
|
||||||
|
@ -523,13 +525,13 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
WHEN("Connecting float input with float output") {
|
WHEN("Connecting float input with float output") {
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"GraphFloatInput",
|
"GraphFloatInput",
|
||||||
graph_resource.getGraphOutputNode(),
|
sGraphGresource.getGraphOutputNode(),
|
||||||
"GraphFloatOutput"));
|
"GraphFloatOutput"));
|
||||||
|
|
||||||
AnimGraph anim_graph = graph_resource.createInstance();
|
AnimGraph anim_graph = sGraphGresource.createInstance();
|
||||||
|
|
||||||
THEN("Writing to the input pointer changes the value of the output.") {
|
THEN("Writing to the input pointer changes the value of the output.") {
|
||||||
float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput");
|
float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput");
|
||||||
|
@ -545,18 +547,18 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
|
|
||||||
WHEN("Connecting adding a Blend2 node") {
|
WHEN("Connecting adding a Blend2 node") {
|
||||||
size_t blend2_node_index =
|
size_t blend2_node_index =
|
||||||
graph_resource.addNode(AnimNodeResourceFactory("Blend2"));
|
sGraphGresource.addNode(AnimNodeResourceFactory("Blend2"));
|
||||||
AnimNodeResource& blend2_node_resource =
|
AnimNodeResource& blend2_node_resource =
|
||||||
graph_resource.m_nodes[blend2_node_index];
|
sGraphGresource.m_nodes[blend2_node_index];
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"GraphFloatInput",
|
"GraphFloatInput",
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Weight"));
|
"Weight"));
|
||||||
|
|
||||||
THEN("Connected float input points to the blend weight.") {
|
THEN("Connected float input points to the blend weight.") {
|
||||||
AnimGraph anim_graph = graph_resource.createInstance();
|
AnimGraph anim_graph = sGraphGresource.createInstance();
|
||||||
|
|
||||||
Blend2Node* blend2_node =
|
Blend2Node* blend2_node =
|
||||||
dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]);
|
dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]);
|
||||||
|
@ -571,28 +573,28 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
WHEN(
|
WHEN(
|
||||||
"Connecting AnimData inputs to blend2 node and blend2 output to graph "
|
"Connecting AnimData inputs to blend2 node and blend2 output to graph "
|
||||||
"output.") {
|
"output.") {
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"GraphAnimInput0",
|
"GraphAnimInput0",
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Input0"));
|
"Input0"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"GraphAnimInput1",
|
"GraphAnimInput1",
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Input1"));
|
"Input1"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Output",
|
"Output",
|
||||||
graph_resource.getGraphOutputNode(),
|
sGraphGresource.getGraphOutputNode(),
|
||||||
"GraphAnimOutput"));
|
"GraphAnimOutput"));
|
||||||
|
|
||||||
THEN(
|
THEN(
|
||||||
"AnimData from output gets blended and result is written to "
|
"AnimData from output gets blended and result is written to "
|
||||||
"Output.") {
|
"Output.") {
|
||||||
AnimGraph anim_graph = graph_resource.createInstance();
|
AnimGraph anim_graph = sGraphGresource.createInstance();
|
||||||
|
|
||||||
Blend2Node* blend2_node =
|
Blend2Node* blend2_node =
|
||||||
dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]);
|
dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]);
|
||||||
|
@ -623,57 +625,57 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
|
|
||||||
WHEN("Adding AnimSampler Nodes") {
|
WHEN("Adding AnimSampler Nodes") {
|
||||||
size_t blend2_node_index =
|
size_t blend2_node_index =
|
||||||
graph_resource.addNode(AnimNodeResourceFactory("Blend2"));
|
sGraphGresource.addNode(AnimNodeResourceFactory("Blend2"));
|
||||||
size_t sampler_node_index =
|
size_t sampler_node_index =
|
||||||
graph_resource.addNode(AnimNodeResourceFactory("AnimSampler"));
|
sGraphGresource.addNode(AnimNodeResourceFactory("AnimSampler"));
|
||||||
size_t speed_scale_node_index =
|
size_t speed_scale_node_index =
|
||||||
graph_resource.addNode(AnimNodeResourceFactory("SpeedScale"));
|
sGraphGresource.addNode(AnimNodeResourceFactory("SpeedScale"));
|
||||||
|
|
||||||
AnimNodeResource& blend2_node_resource =
|
AnimNodeResource& blend2_node_resource =
|
||||||
graph_resource.m_nodes[blend2_node_index];
|
sGraphGresource.m_nodes[blend2_node_index];
|
||||||
AnimNodeResource& sampler_node_resource =
|
AnimNodeResource& sampler_node_resource =
|
||||||
graph_resource.m_nodes[sampler_node_index];
|
sGraphGresource.m_nodes[sampler_node_index];
|
||||||
AnimNodeResource& speed_scale_node_resource =
|
AnimNodeResource& speed_scale_node_resource =
|
||||||
graph_resource.m_nodes[speed_scale_node_index];
|
sGraphGresource.m_nodes[speed_scale_node_index];
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"GraphFloatInput",
|
"GraphFloatInput",
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Weight"));
|
"Weight"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"SpeedScaleInput",
|
"SpeedScaleInput",
|
||||||
speed_scale_node_resource,
|
speed_scale_node_resource,
|
||||||
"SpeedScale"));
|
"SpeedScale"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
graph_resource.getGraphInputNode(),
|
sGraphGresource.getGraphInputNode(),
|
||||||
"GraphAnimInput0",
|
"GraphAnimInput0",
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Input0"));
|
"Input0"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
sampler_node_resource,
|
sampler_node_resource,
|
||||||
"Output",
|
"Output",
|
||||||
speed_scale_node_resource,
|
speed_scale_node_resource,
|
||||||
"Input"));
|
"Input"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
speed_scale_node_resource,
|
speed_scale_node_resource,
|
||||||
"Output",
|
"Output",
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Input1"));
|
"Input1"));
|
||||||
|
|
||||||
REQUIRE(graph_resource.connectSockets(
|
REQUIRE(sGraphGresource.connectSockets(
|
||||||
blend2_node_resource,
|
blend2_node_resource,
|
||||||
"Output",
|
"Output",
|
||||||
graph_resource.getGraphOutputNode(),
|
sGraphGresource.getGraphOutputNode(),
|
||||||
"GraphAnimOutput"));
|
"GraphAnimOutput"));
|
||||||
|
|
||||||
THEN("Data flow and node ordering must be correct.") {
|
THEN("Data flow and node ordering must be correct.") {
|
||||||
AnimGraph anim_graph = graph_resource.createInstance();
|
AnimGraph anim_graph = sGraphGresource.createInstance();
|
||||||
Blend2Node* blend2_node =
|
Blend2Node* blend2_node =
|
||||||
dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]);
|
dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]);
|
||||||
SpeedScaleNode* speed_scale_node = dynamic_cast<SpeedScaleNode*>(
|
SpeedScaleNode* speed_scale_node = dynamic_cast<SpeedScaleNode*>(
|
||||||
|
@ -727,7 +729,7 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
WHEN("Instantiating graph") {
|
WHEN("Instantiating graph") {
|
||||||
AnimGraph anim_graph = graph_resource.createInstance();
|
AnimGraph anim_graph = sGraphGresource.createInstance();
|
||||||
float* blend_weight_input =
|
float* blend_weight_input =
|
||||||
reinterpret_cast<float*>(anim_graph.getInput("GraphFloatInput"));
|
reinterpret_cast<float*>(anim_graph.getInput("GraphFloatInput"));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue