From 0a45497de9c5895db4d90a5acbe8f386336fe978 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 2 Apr 2023 21:40:49 +0200 Subject: [PATCH] Added LockTranslationNode. --- src/AnimGraph/AnimGraphData.h | 16 ++++++++++++++- src/AnimGraph/AnimGraphEditor.cc | 24 +++++++++++++++++++++- src/AnimGraph/AnimGraphNodes.cc | 30 ++++++++++++++++++++++++++++ src/AnimGraph/AnimGraphNodes.h | 32 ++++++++++++++++++++++++++++++ src/AnimGraph/AnimGraphResource.cc | 13 ++++++++++++ 5 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/AnimGraph/AnimGraphData.h b/src/AnimGraph/AnimGraphData.h index 4a14722..b9252ea 100644 --- a/src/AnimGraph/AnimGraphData.h +++ b/src/AnimGraph/AnimGraphData.h @@ -133,6 +133,7 @@ enum class SocketType { SocketTypeUndefined = 0, SocketTypeBool, SocketTypeAnimation, + SocketTypeInt, SocketTypeFloat, SocketTypeVec3, SocketTypeQuat, @@ -143,7 +144,7 @@ enum class SocketType { constexpr size_t cSocketStringValueMaxLength = 256; static const char* SocketTypeNames[] = - {"", "Bool", "Animation", "Float", "Vec3", "Quat", "String"}; + {"", "Bool", "Animation", "Int", "Float", "Vec3", "Quat", "String"}; enum SocketFlags { SocketFlagNone = 0, SocketFlagAffectsTime = 1 }; @@ -152,6 +153,7 @@ struct Socket { SocketType m_type = SocketType::SocketTypeUndefined; union SocketValue { bool flag; + int int_value; float float_value; Vec3 vec3; Quat quat; @@ -172,6 +174,10 @@ struct Socket { m_value.flag = value; } + if constexpr (std::is_same::value) { + m_value.int_value = value; + } + if constexpr (std::is_same::value) { m_value.float_value = value; } @@ -195,6 +201,10 @@ struct Socket { return m_value.flag; } + if constexpr (std::is_same::value) { + return m_value.int_value; + } + if constexpr (std::is_same::value) { return m_value.float_value; } @@ -225,6 +235,10 @@ SocketType GetSocketType() { return SocketType::SocketTypeAnimation; } + if constexpr (std::is_same::value) { + return SocketType::SocketTypeInt; + } + if constexpr (std::is_same::value) { return SocketType::SocketTypeFloat; } diff --git a/src/AnimGraph/AnimGraphEditor.cc b/src/AnimGraph/AnimGraphEditor.cc index df79453..4ead5aa 100644 --- a/src/AnimGraph/AnimGraphEditor.cc +++ b/src/AnimGraph/AnimGraphEditor.cc @@ -18,6 +18,8 @@ ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) { switch (socket_type) { case SocketType::SocketTypeAnimation: return ImNodesPinShape_QuadFilled; + case SocketType::SocketTypeInt: + return ImNodesPinShape_CircleFilled; case SocketType::SocketTypeFloat: return ImNodesPinShape_CircleFilled; case SocketType::SocketTypeVec3: @@ -165,7 +167,12 @@ void AnimGraphEditorRenderSidebar( int num_properties = node_resource.m_socket_accessor->m_properties.size(); for (int i = 0; i < num_properties; i++) { Socket& property = node_resource.m_socket_accessor->m_properties[i]; - if (property.m_type == SocketType::SocketTypeFloat) { + if (property.m_type == SocketType::SocketTypeInt) { + ImGui::InputInt( + property.m_name.c_str(), + reinterpret_cast(&property.m_value.int_value), + 1); + } else if (property.m_type == SocketType::SocketTypeFloat) { ImGui::SliderFloat( property.m_name.c_str(), reinterpret_cast(&property.m_value.float_value), @@ -303,6 +310,10 @@ void AnimGraphEditorUpdate() { node_type_name = "SpeedScale"; } + if (ImGui::MenuItem("LockTranslationNode")) { + node_type_name = "LockTranslationNode"; + } + if (ImGui::MenuItem("MathAddNode")) { node_type_name = "MathAddNode"; } @@ -376,6 +387,17 @@ void AnimGraphEditorUpdate() { ImGui::PopItemWidth(); } + if (!socket_connected && (socket.m_type == SocketType::SocketTypeInt)) { + ImGui::SameLine(); + int socket_value = socket.m_value.int_value; + ImGui::PushItemWidth( + 130.0f - ImGui::CalcTextSize(socket.m_name.c_str()).x); + if (ImGui::InputInt("##hidelabel", &socket_value, 1)) { + socket.SetValue(socket_value); + } + ImGui::PopItemWidth(); + } + ImNodes::PushAttributeFlag( ImNodesAttributeFlags_EnableLinkDetachWithDragClick); ImNodes::EndInputAttribute(); diff --git a/src/AnimGraph/AnimGraphNodes.cc b/src/AnimGraph/AnimGraphNodes.cc index 317dee5..ab5e2d9 100644 --- a/src/AnimGraph/AnimGraphNodes.cc +++ b/src/AnimGraph/AnimGraphNodes.cc @@ -88,4 +88,34 @@ void AnimSamplerNode::Evaluate(AnimGraphContext& context) { if (!sampling_job.Run()) { ozz::log::Err() << "Error sampling animation." << std::endl; } +} + +void LockTranslationNode::Evaluate(AnimGraphContext& context) { + o_output->m_local_matrices = i_input->m_local_matrices; + ozz::math::SoaFloat3 translation = + o_output->m_local_matrices[m_locked_bone_index].translation; + float x[4]; + float y[4]; + float z[4]; + _mm_store_ps(x, translation.x); + _mm_store_ps(y, translation.y); + _mm_store_ps(z, translation.z); + + if (m_lock_x) { + x[0] = 0.f; + } + + if (m_lock_y) { + y[0] = 0.f; + } + + if (m_lock_z) { + z[0] = 0.f; + } + + translation.x = _mm_load_ps(x); + translation.y = _mm_load_ps(y); + translation.z = _mm_load_ps(z); + + o_output->m_local_matrices[m_locked_bone_index].translation = translation; } \ No newline at end of file diff --git a/src/AnimGraph/AnimGraphNodes.h b/src/AnimGraph/AnimGraphNodes.h index 91767cc..fca301d 100644 --- a/src/AnimGraph/AnimGraphNodes.h +++ b/src/AnimGraph/AnimGraphNodes.h @@ -211,6 +211,34 @@ struct NodeDescriptor : public NodeDescriptorBase { } }; +// +// LockTranslationNode +// +struct LockTranslationNode : public AnimNode { + AnimData* i_input = nullptr; + AnimData* o_output = nullptr; + int m_locked_bone_index; + bool m_lock_x; + bool m_lock_y; + bool m_lock_z; + + virtual void Evaluate(AnimGraphContext& context) override; +}; + +template <> +struct NodeDescriptor : public NodeDescriptorBase { + NodeDescriptor(LockTranslationNode* node) { + RegisterInput("Input", &node->i_input); + RegisterOutput("Output", &node->o_output); + + RegisterProperty("BoneIndex", &node->m_locked_bone_index); + RegisterProperty("LockAxisX", &node->m_lock_x); + RegisterProperty("LockAxisY", &node->m_lock_y); + RegisterProperty("LockAxisZ", &node->m_lock_z); + } +}; + + // // ConstScalarNode // @@ -296,6 +324,8 @@ static inline AnimNode* AnimNodeFactory(const std::string& name) { result = new SpeedScaleNode; } else if (name == "AnimSampler") { result = new AnimSamplerNode; + } else if (name == "LockTranslationNode") { + result = new LockTranslationNode; } else if (name == "BlendTree") { result = new BlendTreeNode; } else if (name == "MathAddNode") { @@ -324,6 +354,8 @@ static inline NodeDescriptorBase* AnimNodeDescriptorFactory( return CreateNodeDescriptor(node); } else if (node_type_name == "AnimSampler") { return CreateNodeDescriptor(node); + } else if (node_type_name == "LockTranslationNode") { + return CreateNodeDescriptor(node); } else if (node_type_name == "BlendTree") { return CreateNodeDescriptor(node); } else if (node_type_name == "MathAddNode") { diff --git a/src/AnimGraph/AnimGraphResource.cc b/src/AnimGraph/AnimGraphResource.cc index e2cd57a..1d5f43f 100644 --- a/src/AnimGraph/AnimGraphResource.cc +++ b/src/AnimGraph/AnimGraphResource.cc @@ -35,6 +35,8 @@ json sSocketToJson(const Socket& socket) { if (socket.m_type == SocketType::SocketTypeBool) { result["value"] = socket.m_value.flag; } else if (socket.m_type == SocketType::SocketTypeAnimation) { + } else if (socket.m_type == SocketType::SocketTypeInt) { + result["value"] = socket.m_value.int_value; } else if (socket.m_type == SocketType::SocketTypeFloat) { result["value"] = socket.m_value.float_value; } else if (socket.m_type == SocketType::SocketTypeVec3) { @@ -72,6 +74,12 @@ Socket sJsonToSocket(const json& json_data) { } else if (type_string == "Animation") { result.m_type = SocketType::SocketTypeAnimation; result.m_type_size = sizeof(AnimData); + } else if (type_string == "Int") { + result.m_type = SocketType::SocketTypeInt; + result.m_type_size = sizeof(int); + if (have_value) { + result.m_value.int_value = json_data["value"]; + } } else if (type_string == "Float") { result.m_type = SocketType::SocketTypeFloat; result.m_type_size = sizeof(float); @@ -572,6 +580,11 @@ void AnimGraphResource::setRuntimeNodeProperties(AnimGraph& instance) const { name.c_str(), property.m_value.flag); break; + case SocketType::SocketTypeInt: + node_instance_accessor->SetProperty( + name.c_str(), + property.m_value.int_value); + break; case SocketType::SocketTypeFloat: node_instance_accessor->SetProperty( name.c_str(),