From 196ce997bde9c22ba9afada4519537cf58cf2182 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Mon, 19 Sep 2022 21:18:11 +0200 Subject: [PATCH] CharacterPoseUtil UI: added manual posing mode --- source/main/gfx/GfxCharacter.cpp | 92 ++++++++++--------- .../main/gui/panels/GUI_CharacterPoseUtil.cpp | 62 +++++++++++-- .../main/gui/panels/GUI_CharacterPoseUtil.h | 5 + 3 files changed, 109 insertions(+), 50 deletions(-) diff --git a/source/main/gfx/GfxCharacter.cpp b/source/main/gfx/GfxCharacter.cpp index ddd3382b71..b50b37a477 100644 --- a/source/main/gfx/GfxCharacter.cpp +++ b/source/main/gfx/GfxCharacter.cpp @@ -29,6 +29,7 @@ #include "Console.h" #include "GameContext.h" #include "GfxScene.h" +#include "GUIManager.h" #include "InputEngine.h" #include "MovableText.h" #include "Network.h" @@ -146,62 +147,65 @@ void RoR::GfxCharacter::UpdateCharacterInScene() xc_scenenode->setVisible(true); } - // Reset all anims + if (!App::GetGuiManager()->CharacterPoseUtil.IsManualPoseActive()) + { + // Reset all anims - LOG(fmt::format("file:{}, line:{}, func:{}, resetting all animations before update", __FILE__, __LINE__, __FUNCTION__)); - AnimationStateSet* stateset = entity->getAllAnimationStates(); - for (auto& state_pair: stateset->getAnimationStates()) - { - AnimationState* as = state_pair.second; - as->setEnabled(false); - as->setWeight(0); - LOG(fmt::format("\tanim '{}' was reset", as->getAnimationName())); + LOG(fmt::format("file:{}, line:{}, func:{}, resetting all animations before update", __FILE__, __LINE__, __FUNCTION__)); + AnimationStateSet* stateset = entity->getAllAnimationStates(); + for (auto& state_pair : stateset->getAnimationStates()) + { + AnimationState* as = state_pair.second; + as->setEnabled(false); + as->setWeight(0); + LOG(fmt::format("\tanim '{}' was reset", as->getAnimationName())); } - // upper body anim - if (xc_simbuf.simbuf_anim_upper_name != "") - { - LOG(fmt::format("file:{}, line:{}, func:{}, enabling upper body anim (name '{}', time {})", - __FILE__, __LINE__, __FUNCTION__, - xc_simbuf.simbuf_anim_upper_name, xc_simbuf.simbuf_anim_upper_time)); - try + // upper body anim + if (xc_simbuf.simbuf_anim_upper_name != "") { - this->EnableAnim(entity->getAnimationState(xc_simbuf.simbuf_anim_upper_name), xc_simbuf.simbuf_anim_upper_time); + LOG(fmt::format("file:{}, line:{}, func:{}, enabling upper body anim (name '{}', time {})", + __FILE__, __LINE__, __FUNCTION__, + xc_simbuf.simbuf_anim_upper_name, xc_simbuf.simbuf_anim_upper_time)); + try + { + this->EnableAnim(entity->getAnimationState(xc_simbuf.simbuf_anim_upper_name), xc_simbuf.simbuf_anim_upper_time); + } + catch (Ogre::Exception& eeh) { + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, + fmt::format("error updating upper body anim (name '{}', time {}), message:{}", + xc_simbuf.simbuf_anim_upper_name, xc_simbuf.simbuf_anim_upper_time, eeh.getFullDescription())); + } } - catch (Ogre::Exception& eeh) { - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, - fmt::format("error updating upper body anim (name '{}', time {}), message:{}", - xc_simbuf.simbuf_anim_upper_name, xc_simbuf.simbuf_anim_upper_time, eeh.getFullDescription())); + else + { + LOG(fmt::format("file:{}, line:{}, func:{}, no upper body anim requested", + __FILE__, __LINE__, __FUNCTION__)); } - } - else - { - LOG(fmt::format("file:{}, line:{}, func:{}, no upper body anim requested", - __FILE__, __LINE__, __FUNCTION__)); - } - // lower body anim - if (xc_simbuf.simbuf_anim_lower_name != "") - { - LOG(fmt::format("file:{}, line:{}, func:{}, enabling lower body anim (name '{}', time {})", - __FILE__, __LINE__, __FUNCTION__, - xc_simbuf.simbuf_anim_lower_name, xc_simbuf.simbuf_anim_lower_time)); - try + // lower body anim + if (xc_simbuf.simbuf_anim_lower_name != "") { - this->EnableAnim(entity->getAnimationState(xc_simbuf.simbuf_anim_lower_name), xc_simbuf.simbuf_anim_lower_time); + LOG(fmt::format("file:{}, line:{}, func:{}, enabling lower body anim (name '{}', time {})", + __FILE__, __LINE__, __FUNCTION__, + xc_simbuf.simbuf_anim_lower_name, xc_simbuf.simbuf_anim_lower_time)); + try + { + this->EnableAnim(entity->getAnimationState(xc_simbuf.simbuf_anim_lower_name), xc_simbuf.simbuf_anim_lower_time); + } + catch (Ogre::Exception& eeh) { + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, + fmt::format("error updating lower body anim (name '{}', time {}), message:{}", + xc_simbuf.simbuf_anim_lower_name, xc_simbuf.simbuf_anim_lower_time, eeh.getFullDescription())); + } } - catch (Ogre::Exception& eeh) { - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, - fmt::format("error updating lower body anim (name '{}', time {}), message:{}", - xc_simbuf.simbuf_anim_lower_name, xc_simbuf.simbuf_anim_lower_time, eeh.getFullDescription())); + else + { + LOG(fmt::format("file:{}, line:{}, func:{}, no lower body anim requested", + __FILE__, __LINE__, __FUNCTION__)); } } - else - { - LOG(fmt::format("file:{}, line:{}, func:{}, no lower body anim requested", - __FILE__, __LINE__, __FUNCTION__)); - } // Multiplayer label #ifdef USE_SOCKETW diff --git a/source/main/gui/panels/GUI_CharacterPoseUtil.cpp b/source/main/gui/panels/GUI_CharacterPoseUtil.cpp index 032e36e823..20e1573090 100644 --- a/source/main/gui/panels/GUI_CharacterPoseUtil.cpp +++ b/source/main/gui/panels/GUI_CharacterPoseUtil.cpp @@ -65,20 +65,23 @@ void CharacterPoseUtil::Draw() bool keep_open = true; ImGui::Begin(_LC("CharacterPoseUtil", "Character pose utility"), &keep_open, flags); - ImGui::Dummy(ImVec2(250, 1)); // force minimum width + ImGui::Text("Character: '%s'", gfx_character->xc_instance_name.c_str()); - ImGui::TextDisabled("(gray text means 'disabled')"); + ImGui::Checkbox("Manual pose", &m_manual_pose_active); + if (!m_manual_pose_active) + { + ImGui::TextDisabled("(gray text means 'disabled')"); + } + ImGui::Dummy(ImVec2(350, 1)); // force minimum width ImGui::Separator(); AnimationStateSet* stateset = ent->getAllAnimationStates(); for (auto& state_pair : stateset->getAnimationStates()) { AnimationState* as = state_pair.second; - ImVec4 color = (as->getEnabled()) ? ImGui::GetStyle().Colors[ImGuiCol_Text] : ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]; - ImGui::TextColored(color, "'%s' (%.2f sec)", as->getAnimationName().c_str(), as->getLength()); - std::string caption = fmt::format("{:.2f} sec", as->getTimePosition()); - ImGui::ProgressBar(as->getTimePosition() / as->getLength(), ImVec2(-1, 0), caption.c_str()); + this->DrawAnimControls(as); + } // Common window epilogue: @@ -93,8 +96,55 @@ void CharacterPoseUtil::Draw() } } +void CharacterPoseUtil::DrawAnimControls(Ogre::AnimationState* anim_state) +{ + ImGui::PushID(anim_state); + + // anim name line + ImVec4 color = (anim_state->getEnabled()) ? ImGui::GetStyle().Colors[ImGuiCol_Text] : ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]; + ImGui::TextColored(color, "'%s' (%.2f sec)", anim_state->getAnimationName().c_str(), anim_state->getLength()); + if (m_manual_pose_active) + { + ImGui::SameLine(); + bool enabled = anim_state->getEnabled(); + if (ImGui::Checkbox("Enabled", &enabled)) + { + anim_state->setEnabled(enabled); + anim_state->setWeight(enabled ? 1.f : 0.f); + } + ImGui::SameLine(); + float weight = anim_state->getWeight(); + ImGui::SetNextItemWidth(50.f); + if (ImGui::InputFloat("Weight", &weight)) + { + anim_state->setWeight(weight); + } + } + + // anim progress line + if (m_manual_pose_active) + { + float timepos = anim_state->getTimePosition(); + if (ImGui::SliderFloat("Time pos", &timepos, 0.f, anim_state->getLength())) + { + anim_state->setTimePosition(timepos); + } + } + else + { + std::string caption = fmt::format("{:.2f} sec", anim_state->getTimePosition()); + ImGui::ProgressBar(anim_state->getTimePosition() / anim_state->getLength(), ImVec2(-1, 0), caption.c_str()); + } + + ImGui::PopID(); // AnimationState* +} + void CharacterPoseUtil::SetVisible(bool v) { m_is_visible = v; m_is_hovered = false; + if (!v) + { + m_manual_pose_active = false; + } } diff --git a/source/main/gui/panels/GUI_CharacterPoseUtil.h b/source/main/gui/panels/GUI_CharacterPoseUtil.h index b0d7cf15c9..9905d3b34f 100644 --- a/source/main/gui/panels/GUI_CharacterPoseUtil.h +++ b/source/main/gui/panels/GUI_CharacterPoseUtil.h @@ -34,10 +34,15 @@ class CharacterPoseUtil bool IsVisible() const { return m_is_visible; } bool IsHovered() const { return IsVisible() && m_is_hovered; } + bool IsManualPoseActive() const { return m_manual_pose_active; } + private: + void DrawAnimControls(Ogre::AnimationState* anim_state); + bool m_is_visible = false; bool m_is_hovered = false; + bool m_manual_pose_active = false; }; } // namespace GUI