Initial works for actial animation sampling and graph evaluation.

This commit is contained in:
Martin Felis
2022-04-11 16:46:09 +02:00
parent bf0c7a7daa
commit eeef635c64
9 changed files with 430 additions and 158 deletions
+72 -36
View File
@@ -27,25 +27,23 @@ json sSocketToJson(const Socket& socket) {
result["name"] = socket.m_name;
result["type"] = sSocketTypeToStr(socket.m_type);
if (socket.m_value.ptr != nullptr) {
if (socket.m_reference.ptr != nullptr) {
if (socket.m_type == SocketType::SocketTypeBool) {
result["value"] = *reinterpret_cast<bool*>(socket.m_value.ptr);
result["value"] = socket.m_value.flag;
} else if (socket.m_type == SocketType::SocketTypeAnimation) {
} else if (socket.m_type == SocketType::SocketTypeFloat) {
result["value"] = *reinterpret_cast<float*>(socket.m_value.ptr);
result["value"] = socket.m_value.float_value;
} else if (socket.m_type == SocketType::SocketTypeVec3) {
Vec3& vec3 = *reinterpret_cast<Vec3*>(socket.m_value.ptr);
result["value"][0] = vec3[0];
result["value"][1] = vec3[1];
result["value"][2] = vec3[2];
result["value"][0] = socket.m_value.vec3[0];
result["value"][1] = socket.m_value.vec3[1];
result["value"][2] = socket.m_value.vec3[2];
} else if (socket.m_type == SocketType::SocketTypeQuat) {
Quat& quat = *reinterpret_cast<Quat*>(socket.m_value.ptr);
result["value"][0] = quat[0];
result["value"][1] = quat[1];
result["value"][2] = quat[2];
result["value"][3] = quat[3];
result["value"][0] = socket.m_value.quat[0];
result["value"][1] = socket.m_value.quat[1];
result["value"][2] = socket.m_value.quat[2];
result["value"][3] = socket.m_value.quat[3];
} else if (socket.m_type == SocketType::SocketTypeString) {
result["value"] = *reinterpret_cast<std::string*>(socket.m_value.ptr);
result["value"] = std::string(socket.m_value.str);
} else {
std::cerr << "Invalid socket type '" << static_cast<int>(socket.m_type)
<< "'." << std::endl;
@@ -57,7 +55,7 @@ json sSocketToJson(const Socket& socket) {
Socket sJsonToSocket(const json& json_data) {
Socket result;
result.m_type = SocketType::SocketTypeUndefined;
result.m_value.ptr = nullptr;
result.m_reference.ptr = nullptr;
result.m_name = json_data["name"];
std::string type_string = json_data["type"];
@@ -129,29 +127,30 @@ AnimNodeResource sAnimGraphNodeFromJson(const json& json_node) {
if (sSocketTypeToStr(property.m_type) == json_property["type"]) {
if (property.m_type == SocketType::SocketTypeBool) {
result.m_socket_accessor->SetProperty<bool>(
property.m_name,
json_property["value"]);
property.m_value.flag = json_property["value"];
} else if (property.m_type == SocketType::SocketTypeAnimation) {
} else if (property.m_type == SocketType::SocketTypeFloat) {
result.m_socket_accessor->SetProperty<float>(
property.m_name,
json_property["value"]);
property.m_value.float_value = json_property["value"];
} else if (property.m_type == SocketType::SocketTypeVec3) {
Vec3* property_vec3 = reinterpret_cast<Vec3*>(property.m_value.ptr);
(*property_vec3)[0] = json_property["value"][0];
(*property_vec3)[1] = json_property["value"][1];
(*property_vec3)[2] = json_property["value"][2];
property.m_value.vec3[0] = json_property["value"][0];
property.m_value.vec3[1] = json_property["value"][1];
property.m_value.vec3[2] = json_property["value"][2];
} else if (property.m_type == SocketType::SocketTypeQuat) {
Quat* property_quat = reinterpret_cast<Quat*>(property.m_value.ptr);
(*property_quat)[0] = json_property["value"][0];
(*property_quat)[1] = json_property["value"][1];
(*property_quat)[2] = json_property["value"][2];
(*property_quat)[3] = json_property["value"][3];
Quat* property_quat = reinterpret_cast<Quat*>(property.m_reference.ptr);
property.m_value.quat[0] = json_property["value"][0];
property.m_value.quat[1] = json_property["value"][1];
property.m_value.quat[2] = json_property["value"][2];
property.m_value.quat[3] = json_property["value"][3];
} else if (property.m_type == SocketType::SocketTypeString) {
result.m_socket_accessor->SetProperty<std::string>(
property.m_name,
json_property["value"]);
std::string value_str = json_property["value"];
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 {
std::cerr << "Invalid type for property '" << property.m_name
<< "'. Cannot parse json to type '"
@@ -345,6 +344,7 @@ AnimGraph AnimGraphResource::createInstance() const {
createRuntimeNodeInstances(result);
prepareGraphIOData(result);
connectRuntimeNodes(result);
setRuntimeNodeProperties(result);
result.updateOrderedNodes();
result.reset();
@@ -387,7 +387,7 @@ void AnimGraphResource::prepareGraphIOData(AnimGraph& instance) const {
int input_block_offset = 0;
for (int i = 0; i < graph_inputs.size(); i++) {
graph_inputs[i].m_value.ptr =
graph_inputs[i].m_reference.ptr =
(void*)&instance.m_input_buffer[input_block_offset];
input_block_offset += sizeof(void*);
}
@@ -403,7 +403,7 @@ void AnimGraphResource::prepareGraphIOData(AnimGraph& instance) const {
int output_block_offset = 0;
for (int i = 0; i < graph_outputs.size(); i++) {
graph_outputs[i].m_value.ptr =
graph_outputs[i].m_reference.ptr =
(void*)&instance.m_output_buffer[output_block_offset];
output_block_offset += graph_outputs[i].m_type_size;
}
@@ -486,8 +486,8 @@ void AnimGraphResource::connectRuntimeNodes(AnimGraph& instance) const {
//
// Wire up outputs to inputs.
//
(*target_socket->m_value.ptr_ptr) = source_socket->m_value.ptr;
// (*source_socket->m_value.ptr_ptr) = target_socket->m_value.ptr;
(*target_socket->m_reference.ptr_ptr) = source_socket->m_reference.ptr;
// (*source_socket->m_reference.ptr_ptr) = target_socket->m_reference.ptr;
size_t target_node_index = target_node->m_index;
@@ -516,3 +516,39 @@ void AnimGraphResource::connectRuntimeNodes(AnimGraph& instance) const {
}
}
void AnimGraphResource::setRuntimeNodeProperties(AnimGraph& instance) const {
for (int i = 2; i < m_nodes.size(); i++) {
const AnimNodeResource& node_resource = m_nodes[i];
NodeSocketAccessorBase* node_instance_accessor =
AnimNodeAccessorFactory(node_resource.m_type_name, instance.m_nodes[i]);
std::vector<Socket>& resource_properties = node_resource.m_socket_accessor->m_properties;
for (size_t j = 0, n = resource_properties.size(); j < n; j++) {
const Socket& property = resource_properties[j];
const std::string& name = property.m_name;
switch (property.m_type) {
case SocketType::SocketTypeBool:
node_instance_accessor->SetPropertyReferenceValue<const bool&>(name, property.m_value.flag);
break;
case SocketType::SocketTypeFloat:
node_instance_accessor->SetPropertyReferenceValue(name, property.m_value.float_value);
break;
case SocketType::SocketTypeVec3:
node_instance_accessor->SetPropertyReferenceValue(name, property.m_value.vec3);
break;
case SocketType::SocketTypeQuat:
node_instance_accessor->SetPropertyReferenceValue(name, property.m_value.quat);
break;
case SocketType::SocketTypeString:
node_instance_accessor->SetPropertyReferenceValue(name, property.m_value.str);
break;
default:
std::cerr << "Invalid socket type " << static_cast<int>(property.m_type) << std::endl;
}
}
delete node_instance_accessor;
}
}