From 0a8bb7c7c657b49ad9e3029cfd17b142c84a1d66 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Fri, 24 Mar 2023 09:10:08 +0800 Subject: [PATCH] Make skeletons capable of containing poses --- src/engine/animation/skeleton.cpp | 45 ++++ src/engine/animation/skeleton.hpp | 41 ++++ src/game/ant/ant-morphogenesis.cpp | 40 ++-- src/game/states/nest-selection-state.cpp | 264 +++++++++++++++++++++-- 4 files changed, 350 insertions(+), 40 deletions(-) diff --git a/src/engine/animation/skeleton.cpp b/src/engine/animation/skeleton.cpp index 0841234..3239688 100644 --- a/src/engine/animation/skeleton.cpp +++ b/src/engine/animation/skeleton.cpp @@ -60,6 +60,31 @@ void skeleton::remove_bones() m_rest_pose.resize(); } +animation_pose& skeleton::add_pose(hash::fnv1a32_t name) +{ + const auto [iterator, inserted] = m_pose_map.emplace(name, *this); + + if (!inserted) + { + throw std::invalid_argument("Duplicate pose name"); + } + + return iterator->second; +} + +void skeleton::remove_pose(hash::fnv1a32_t name) +{ + if (!m_pose_map.erase(name)) + { + throw std::invalid_argument("Pose not found"); + } +} + +void skeleton::remove_poses() +{ + m_pose_map.clear(); +} + void skeleton::set_bone_parent(bone_index_type child_index, bone_index_type parent_index) { if (child_index < parent_index) @@ -94,3 +119,23 @@ std::optional skeleton::get_bone_index(hash::fnv1a32_t name) co return std::nullopt; } + +const animation_pose* skeleton::get_pose(hash::fnv1a32_t name) const +{ + if (auto i = m_pose_map.find(name); i != m_pose_map.end()) + { + return &i->second; + } + + return nullptr; +} + +animation_pose* skeleton::get_pose(hash::fnv1a32_t name) +{ + if (auto i = m_pose_map.find(name); i != m_pose_map.end()) + { + return &i->second; + } + + return nullptr; +} diff --git a/src/engine/animation/skeleton.hpp b/src/engine/animation/skeleton.hpp index 5c27434..dd277e3 100644 --- a/src/engine/animation/skeleton.hpp +++ b/src/engine/animation/skeleton.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -83,6 +84,31 @@ public: */ void remove_bones(); + /** + * Adds a pose to the skeleton. + * + * @param name Name of the pose. + * + * @return Reference to the added pose. + * + * @throw std::invalid_argument Duplicate pose name. + */ + animation_pose& add_pose(hash::fnv1a32_t name); + + /** + * Removes a pose from the skeleton. + * + * @param name Name of the pose to remove. + * + * @throw std::invalid_argument Pose not found. + */ + void remove_pose(hash::fnv1a32_t name); + + /** + * Removes all poses from the skeleton, excluding the rest pose. + */ + void remove_poses(); + /** * Sets the parent of a bone. * @@ -145,6 +171,18 @@ public: */ [[nodiscard]] std::optional get_bone_index(hash::fnv1a32_t name) const; + /** + * Finds a pose from the poses's name. + * + * @param name Name of a pose. + * + * @return Non-owning pointer to the pose, or `nullptr` if no pose with the given name was found. + */ + /// @{ + [[nodiscard]] const animation_pose* get_pose(hash::fnv1a32_t name) const; + [[nodiscard]] animation_pose* get_pose(hash::fnv1a32_t name); + /// @} + /// Returns the skeleton's rest pose. [[nodiscard]] inline const rest_pose& get_rest_pose() const noexcept { @@ -160,6 +198,9 @@ private: /// Map of bone names to bone indices. std::unordered_map m_bone_map; + + /// Map of pose names to poses. + std::unordered_map m_pose_map; }; #endif // ANTKEEPER_ANIMATION_SKELETON_HPP diff --git a/src/game/ant/ant-morphogenesis.cpp b/src/game/ant/ant-morphogenesis.cpp index 4079393..69adebe 100644 --- a/src/game/ant/ant-morphogenesis.cpp +++ b/src/game/ant/ant-morphogenesis.cpp @@ -499,33 +499,46 @@ void build_ant_rest_pose(const ant_phenome& phenome, const ant_bone_set& bones, return skeleton.get_rest_pose().get_relative_transform(*skeleton.get_bone_index(bone_name)); }; + const auto& mesosoma_transform = get_bone_transform(mesosoma_skeleton, "mesosoma"); + const auto& head_socket_transform = get_bone_transform(mesosoma_skeleton, "head"); + const auto& head_transform = get_bone_transform(head_skeleton, "head"); + + const auto inverse_mesosoma_transform = math::inverse(mesosoma_transform); + // Build skeleton rest pose - skeleton.set_bone_transform(*bones.mesosoma, get_bone_transform(mesosoma_skeleton, "mesosoma")); - skeleton.set_bone_transform(*bones.procoxa_l, get_bone_transform(legs_skeleton, "procoxa_l")); + skeleton.set_bone_transform(*bones.mesosoma, mesosoma_transform); + + skeleton.set_bone_transform(*bones.procoxa_l, inverse_mesosoma_transform * get_bone_transform(legs_skeleton, "procoxa_l")); skeleton.set_bone_transform(*bones.profemur_l, get_bone_transform(legs_skeleton, "profemur_l")); skeleton.set_bone_transform(*bones.protibia_l, get_bone_transform(legs_skeleton, "protibia_l")); skeleton.set_bone_transform(*bones.protarsus_l, get_bone_transform(legs_skeleton, "protarsus1_l")); - skeleton.set_bone_transform(*bones.procoxa_r, get_bone_transform(legs_skeleton, "procoxa_r")); + + skeleton.set_bone_transform(*bones.procoxa_r, inverse_mesosoma_transform * get_bone_transform(legs_skeleton, "procoxa_r")); skeleton.set_bone_transform(*bones.profemur_r, get_bone_transform(legs_skeleton, "profemur_r")); skeleton.set_bone_transform(*bones.protibia_r, get_bone_transform(legs_skeleton, "protibia_r")); skeleton.set_bone_transform(*bones.protarsus_r, get_bone_transform(legs_skeleton, "protarsus1_r")); - skeleton.set_bone_transform(*bones.mesocoxa_l, get_bone_transform(legs_skeleton, "mesocoxa_l")); + + skeleton.set_bone_transform(*bones.mesocoxa_l, inverse_mesosoma_transform * get_bone_transform(legs_skeleton, "mesocoxa_l")); skeleton.set_bone_transform(*bones.mesofemur_l, get_bone_transform(legs_skeleton, "mesofemur_l")); skeleton.set_bone_transform(*bones.mesotibia_l, get_bone_transform(legs_skeleton, "mesotibia_l")); skeleton.set_bone_transform(*bones.mesotarsus_l, get_bone_transform(legs_skeleton, "mesotarsus1_l")); - skeleton.set_bone_transform(*bones.mesocoxa_r, get_bone_transform(legs_skeleton, "mesocoxa_r")); + + skeleton.set_bone_transform(*bones.mesocoxa_r, inverse_mesosoma_transform * get_bone_transform(legs_skeleton, "mesocoxa_r")); skeleton.set_bone_transform(*bones.mesofemur_r, get_bone_transform(legs_skeleton, "mesofemur_r")); skeleton.set_bone_transform(*bones.mesotibia_r, get_bone_transform(legs_skeleton, "mesotibia_r")); skeleton.set_bone_transform(*bones.mesotarsus_r, get_bone_transform(legs_skeleton, "mesotarsus1_r")); - skeleton.set_bone_transform(*bones.metacoxa_l, get_bone_transform(legs_skeleton, "metacoxa_l")); + + skeleton.set_bone_transform(*bones.metacoxa_l, inverse_mesosoma_transform * get_bone_transform(legs_skeleton, "metacoxa_l")); skeleton.set_bone_transform(*bones.metafemur_l, get_bone_transform(legs_skeleton, "metafemur_l")); skeleton.set_bone_transform(*bones.metatibia_l, get_bone_transform(legs_skeleton, "metatibia_l")); skeleton.set_bone_transform(*bones.metatarsus_l, get_bone_transform(legs_skeleton, "metatarsus1_l")); - skeleton.set_bone_transform(*bones.metacoxa_r, get_bone_transform(legs_skeleton, "metacoxa_r")); + + skeleton.set_bone_transform(*bones.metacoxa_r, inverse_mesosoma_transform * get_bone_transform(legs_skeleton, "metacoxa_r")); skeleton.set_bone_transform(*bones.metafemur_r, get_bone_transform(legs_skeleton, "metafemur_r")); skeleton.set_bone_transform(*bones.metatibia_r, get_bone_transform(legs_skeleton, "metatibia_r")); skeleton.set_bone_transform(*bones.metatarsus_r, get_bone_transform(legs_skeleton, "metatarsus1_r")); - skeleton.set_bone_transform(*bones.head, get_bone_transform(mesosoma_skeleton, "head") * get_bone_transform(head_skeleton, "head")); + + skeleton.set_bone_transform(*bones.head, head_socket_transform * head_transform); skeleton.set_bone_transform(*bones.mandible_l, get_bone_transform(head_skeleton, "mandible_l") * get_bone_transform(mandibles_skeleton, "mandible_l")); skeleton.set_bone_transform(*bones.mandible_r, get_bone_transform(head_skeleton, "mandible_r") * get_bone_transform(mandibles_skeleton, "mandible_r")); skeleton.set_bone_transform(*bones.antennomere1_l, get_bone_transform(head_skeleton, "antenna_l") * get_bone_transform(antennae_skeleton, "antennomere1_l")); @@ -541,17 +554,10 @@ void build_ant_rest_pose(const ant_phenome& phenome, const ant_bone_set& bones, if (bones.postpetiole) { skeleton.set_bone_transform(*bones.postpetiole, get_bone_transform(waist_skeleton, "postpetiole")); - skeleton.set_bone_transform(*bones.gaster, get_bone_transform(waist_skeleton, "postpetiole") * get_bone_transform(gaster_skeleton, "gaster")); - } - else if (bones.petiole) - { - skeleton.set_bone_transform(*bones.gaster, get_bone_transform(waist_skeleton, "petiole") * get_bone_transform(gaster_skeleton, "gaster")); - } - else - { - skeleton.set_bone_transform(*bones.gaster, get_bone_transform(mesosoma_skeleton, "petiole") * get_bone_transform(gaster_skeleton, "gaster")); } + skeleton.set_bone_transform(*bones.gaster, get_bone_transform(waist_skeleton, "gaster") * get_bone_transform(gaster_skeleton, "gaster")); + if (bones.sting) { skeleton.set_bone_transform(*bones.sting, get_bone_transform(gaster_skeleton, "sting") * get_bone_transform(*sting_skeleton, "sting")); diff --git a/src/game/states/nest-selection-state.cpp b/src/game/states/nest-selection-state.cpp index 4af0c21..c9ab974 100644 --- a/src/game/states/nest-selection-state.cpp +++ b/src/game/states/nest-selection-state.cpp @@ -128,24 +128,240 @@ nest_selection_state::nest_selection_state(::game& ctx): // Create worker entity(s) - auto worker_skeletal_mesh = std::make_unique(worker_model); + - const auto& worker_skeleton = worker_model->get_skeleton(); + auto& worker_skeleton = worker_model->get_skeleton(); const auto& worker_rest_pose = worker_skeleton.get_rest_pose(); - auto& worker_pose = worker_skeletal_mesh->get_pose(); - const float mandibles_open_angle = math::radians(32.0f); - auto open_left_mandible = math::transform::identity(); - open_left_mandible.rotation = math::angle_axis(-mandibles_open_angle, float3{0, 0, 1}); - auto open_right_mandible = math::transform::identity(); - open_right_mandible.rotation = math::angle_axis(mandibles_open_angle, float3{0, 0, 1}); + auto& pupal_pose = worker_skeleton.add_pose("pupal"); + + // Fold forelegs + { + const float procoxa_fold_angle_y = math::radians(30.0f); + const float procoxa_fold_angle_z = math::radians(25.0f); + const float procoxa_fold_angle_x = math::radians(15.0f); + auto fold_procoxa_l = math::transform::identity(); + auto fold_procoxa_r = math::transform::identity(); + fold_procoxa_l.rotation = math::angle_axis(procoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(procoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(procoxa_fold_angle_x, float3{1, 0, 0}); + fold_procoxa_r.rotation = math::angle_axis(-procoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-procoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(procoxa_fold_angle_x, float3{1, 0, 0}); + + const float profemur_fold_angle_z = math::radians(20.0f); + const float profemur_fold_angle_x = math::radians(80.0f); + auto fold_profemur_l = math::transform::identity(); + auto fold_profemur_r = math::transform::identity(); + fold_profemur_l.rotation = math::angle_axis(profemur_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(profemur_fold_angle_x, float3{1, 0, 0}); + fold_profemur_r.rotation = math::angle_axis(-profemur_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(profemur_fold_angle_x, float3{1, 0, 0}); + + const float protibia_fold_angle = math::radians(165.0f); + auto fold_protibia_l = math::transform::identity(); + auto fold_protibia_r = math::transform::identity(); + fold_protibia_l.rotation = math::angle_axis(-protibia_fold_angle, float3{1, 0, 0}); + fold_protibia_r.rotation = math::angle_axis(-protibia_fold_angle, float3{1, 0, 0}); + + const float protarsus_fold_angle = math::radians(20.0f); + auto fold_protarsus_l = math::transform::identity(); + auto fold_protarsus_r = math::transform::identity(); + fold_protarsus_l.rotation = math::angle_axis(-protarsus_fold_angle, float3{1, 0, 0}); + fold_protarsus_r.rotation = math::angle_axis(-protarsus_fold_angle, float3{1, 0, 0}); + + auto procoxa_l_bone = *worker_skeleton.get_bone_index("procoxa_l"); + auto procoxa_r_bone = *worker_skeleton.get_bone_index("procoxa_r"); + auto profemur_l_bone = *worker_skeleton.get_bone_index("profemur_l"); + auto profemur_r_bone = *worker_skeleton.get_bone_index("profemur_r"); + auto protibia_l_bone = *worker_skeleton.get_bone_index("protibia_l"); + auto protibia_r_bone = *worker_skeleton.get_bone_index("protibia_r"); + auto protarsus_l_bone = *worker_skeleton.get_bone_index("protarsus_l"); + auto protarsus_r_bone = *worker_skeleton.get_bone_index("protarsus_r"); + + pupal_pose.set_relative_transform(procoxa_l_bone, worker_rest_pose.get_relative_transform(procoxa_l_bone) * fold_procoxa_l); + pupal_pose.set_relative_transform(procoxa_r_bone, worker_rest_pose.get_relative_transform(procoxa_r_bone) * fold_procoxa_r); + pupal_pose.set_relative_transform(profemur_l_bone, worker_rest_pose.get_relative_transform(profemur_l_bone) * fold_profemur_l); + pupal_pose.set_relative_transform(profemur_r_bone, worker_rest_pose.get_relative_transform(profemur_r_bone) * fold_profemur_r); + pupal_pose.set_relative_transform(protibia_l_bone, worker_rest_pose.get_relative_transform(protibia_l_bone) * fold_protibia_l); + pupal_pose.set_relative_transform(protibia_r_bone, worker_rest_pose.get_relative_transform(protibia_r_bone) * fold_protibia_r); + pupal_pose.set_relative_transform(protarsus_l_bone, worker_rest_pose.get_relative_transform(protarsus_l_bone) * fold_protarsus_l); + pupal_pose.set_relative_transform(protarsus_r_bone, worker_rest_pose.get_relative_transform(protarsus_r_bone) * fold_protarsus_r); + } + + // Fold midlegs + { + const float mesocoxa_fold_angle_z = math::radians(45.0f); + const float mesocoxa_fold_angle_y = math::radians(45.0f); + const float mesocoxa_fold_angle_x = math::radians(10.0f); + auto fold_mesocoxa_l = math::transform::identity(); + auto fold_mesocoxa_r = math::transform::identity(); + fold_mesocoxa_l.rotation = math::angle_axis(-mesocoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(mesocoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-mesocoxa_fold_angle_x, float3{1, 0, 0}); + fold_mesocoxa_r.rotation = math::angle_axis(mesocoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(-mesocoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-mesocoxa_fold_angle_x, float3{1, 0, 0}); + + const float mesofemur_fold_angle = math::radians(90.0f); + auto fold_mesofemur_l = math::transform::identity(); + auto fold_mesofemur_r = math::transform::identity(); + fold_mesofemur_l.rotation = math::angle_axis(mesofemur_fold_angle, float3{1, 0, 0}); + fold_mesofemur_r.rotation = math::angle_axis(mesofemur_fold_angle, float3{1, 0, 0}); + + const float mesotibia_fold_angle = math::radians(162.0f); + auto fold_mesotibia_l = math::transform::identity(); + auto fold_mesotibia_r = math::transform::identity(); + fold_mesotibia_l.rotation = math::angle_axis(-mesotibia_fold_angle, float3{1, 0, 0}); + fold_mesotibia_r.rotation = math::angle_axis(-mesotibia_fold_angle, float3{1, 0, 0}); + + const float mesotarsus_fold_angle = math::radians(20.0f); + auto fold_mesotarsus_l = math::transform::identity(); + auto fold_mesotarsus_r = math::transform::identity(); + fold_mesotarsus_l.rotation = math::angle_axis(-mesotarsus_fold_angle, float3{1, 0, 0}); + fold_mesotarsus_r.rotation = math::angle_axis(-mesotarsus_fold_angle, float3{1, 0, 0}); + + auto mesocoxa_l_bone = *worker_skeleton.get_bone_index("mesocoxa_l"); + auto mesocoxa_r_bone = *worker_skeleton.get_bone_index("mesocoxa_r"); + auto mesofemur_l_bone = *worker_skeleton.get_bone_index("mesofemur_l"); + auto mesofemur_r_bone = *worker_skeleton.get_bone_index("mesofemur_r"); + auto mesotibia_l_bone = *worker_skeleton.get_bone_index("mesotibia_l"); + auto mesotibia_r_bone = *worker_skeleton.get_bone_index("mesotibia_r"); + auto mesotarsus_l_bone = *worker_skeleton.get_bone_index("mesotarsus_l"); + auto mesotarsus_r_bone = *worker_skeleton.get_bone_index("mesotarsus_r"); + + pupal_pose.set_relative_transform(mesocoxa_l_bone, worker_rest_pose.get_relative_transform(mesocoxa_l_bone) * fold_mesocoxa_l); + pupal_pose.set_relative_transform(mesocoxa_r_bone, worker_rest_pose.get_relative_transform(mesocoxa_r_bone) * fold_mesocoxa_r); + pupal_pose.set_relative_transform(mesofemur_l_bone, worker_rest_pose.get_relative_transform(mesofemur_l_bone) * fold_mesofemur_l); + pupal_pose.set_relative_transform(mesofemur_r_bone, worker_rest_pose.get_relative_transform(mesofemur_r_bone) * fold_mesofemur_r); + pupal_pose.set_relative_transform(mesotibia_l_bone, worker_rest_pose.get_relative_transform(mesotibia_l_bone) * fold_mesotibia_l); + pupal_pose.set_relative_transform(mesotibia_r_bone, worker_rest_pose.get_relative_transform(mesotibia_r_bone) * fold_mesotibia_r); + pupal_pose.set_relative_transform(mesotarsus_l_bone, worker_rest_pose.get_relative_transform(mesotarsus_l_bone) * fold_mesotarsus_l); + pupal_pose.set_relative_transform(mesotarsus_r_bone, worker_rest_pose.get_relative_transform(mesotarsus_r_bone) * fold_mesotarsus_r); + } + + // Fold hindlegs + { + const float metacoxa_fold_angle_z = math::radians(15.0f); + const float metacoxa_fold_angle_y = math::radians(10.0f); + const float metacoxa_fold_angle_x = math::radians(25.0f); + auto fold_metacoxa_l = math::transform::identity(); + auto fold_metacoxa_r = math::transform::identity(); + fold_metacoxa_l.rotation = math::angle_axis(-metacoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(-metacoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(metacoxa_fold_angle_x, float3{1, 0, 0}); + fold_metacoxa_r.rotation = math::angle_axis(metacoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(metacoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(metacoxa_fold_angle_x, float3{1, 0, 0}); + + const float metafemur_fold_angle = math::radians(105.0f); + auto fold_metafemur_l = math::transform::identity(); + auto fold_metafemur_r = math::transform::identity(); + fold_metafemur_l.rotation = math::angle_axis(metafemur_fold_angle, float3{1, 0, 0}); + fold_metafemur_r.rotation = math::angle_axis(metafemur_fold_angle, float3{1, 0, 0}); + + const float metatibia_fold_angle = math::radians(165.0f); + auto fold_metatibia_l = math::transform::identity(); + auto fold_metatibia_r = math::transform::identity(); + fold_metatibia_l.rotation = math::angle_axis(-metatibia_fold_angle, float3{1, 0, 0}); + fold_metatibia_r.rotation = math::angle_axis(-metatibia_fold_angle, float3{1, 0, 0}); + + const float metatarsus_fold_angle = math::radians(0.0f); + auto fold_metatarsus_l = math::transform::identity(); + auto fold_metatarsus_r = math::transform::identity(); + fold_metatarsus_l.rotation = math::angle_axis(-metatarsus_fold_angle, float3{1, 0, 0}); + fold_metatarsus_r.rotation = math::angle_axis(-metatarsus_fold_angle, float3{1, 0, 0}); + + auto metacoxa_l_bone = *worker_skeleton.get_bone_index("metacoxa_l"); + auto metacoxa_r_bone = *worker_skeleton.get_bone_index("metacoxa_r"); + auto metafemur_l_bone = *worker_skeleton.get_bone_index("metafemur_l"); + auto metafemur_r_bone = *worker_skeleton.get_bone_index("metafemur_r"); + auto metatibia_l_bone = *worker_skeleton.get_bone_index("metatibia_l"); + auto metatibia_r_bone = *worker_skeleton.get_bone_index("metatibia_r"); + auto metatarsus_l_bone = *worker_skeleton.get_bone_index("metatarsus_l"); + auto metatarsus_r_bone = *worker_skeleton.get_bone_index("metatarsus_r"); + + pupal_pose.set_relative_transform(metacoxa_l_bone, worker_rest_pose.get_relative_transform(metacoxa_l_bone) * fold_metacoxa_l); + pupal_pose.set_relative_transform(metacoxa_r_bone, worker_rest_pose.get_relative_transform(metacoxa_r_bone) * fold_metacoxa_r); + pupal_pose.set_relative_transform(metafemur_l_bone, worker_rest_pose.get_relative_transform(metafemur_l_bone) * fold_metafemur_l); + pupal_pose.set_relative_transform(metafemur_r_bone, worker_rest_pose.get_relative_transform(metafemur_r_bone) * fold_metafemur_r); + pupal_pose.set_relative_transform(metatibia_l_bone, worker_rest_pose.get_relative_transform(metatibia_l_bone) * fold_metatibia_l); + pupal_pose.set_relative_transform(metatibia_r_bone, worker_rest_pose.get_relative_transform(metatibia_r_bone) * fold_metatibia_r); + pupal_pose.set_relative_transform(metatarsus_l_bone, worker_rest_pose.get_relative_transform(metatarsus_l_bone) * fold_metatarsus_l); + pupal_pose.set_relative_transform(metatarsus_r_bone, worker_rest_pose.get_relative_transform(metatarsus_r_bone) * fold_metatarsus_r); + } + + // Fold head + { + const float head_fold_angle = math::radians(80.0f); + auto fold_head = math::transform::identity(); + fold_head.rotation = math::angle_axis(-head_fold_angle, float3{1, 0, 0}); + + auto head_bone = *worker_skeleton.get_bone_index("head"); + + pupal_pose.set_relative_transform(head_bone, worker_rest_pose.get_relative_transform(head_bone) * fold_head); + } + + // Fold antennae + { + const float antennomere1_fold_angle_y = math::radians(70.0f); + const float antennomere1_fold_angle_x = math::radians(45.0f); + auto fold_antennomere1_l = math::transform::identity(); + auto fold_antennomere1_r = math::transform::identity(); + fold_antennomere1_l.rotation = math::angle_axis(-antennomere1_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere1_fold_angle_x, float3{1, 0, 0}); + fold_antennomere1_r.rotation = math::angle_axis(antennomere1_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere1_fold_angle_x, float3{1, 0, 0}); + + const float antennomere2_fold_angle_y = math::radians(75.0f); + const float antennomere2_fold_angle_x = math::radians(25.0f); + auto fold_antennomere2_l = math::transform::identity(); + auto fold_antennomere2_r = math::transform::identity(); + fold_antennomere2_l.rotation = math::angle_axis(antennomere2_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere2_fold_angle_x, float3{1, 0, 0}); + fold_antennomere2_r.rotation = math::angle_axis(-antennomere2_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere2_fold_angle_x, float3{1, 0, 0}); + + auto antennomere1_l_bone = *worker_skeleton.get_bone_index("antennomere1_l"); + auto antennomere1_r_bone = *worker_skeleton.get_bone_index("antennomere1_r"); + auto antennomere2_l_bone = *worker_skeleton.get_bone_index("antennomere2_l"); + auto antennomere2_r_bone = *worker_skeleton.get_bone_index("antennomere2_r"); + + pupal_pose.set_relative_transform(antennomere1_l_bone, worker_rest_pose.get_relative_transform(antennomere1_l_bone) * fold_antennomere1_l); + pupal_pose.set_relative_transform(antennomere1_r_bone, worker_rest_pose.get_relative_transform(antennomere1_r_bone) * fold_antennomere1_r); + pupal_pose.set_relative_transform(antennomere2_l_bone, worker_rest_pose.get_relative_transform(antennomere2_l_bone) * fold_antennomere2_l); + pupal_pose.set_relative_transform(antennomere2_r_bone, worker_rest_pose.get_relative_transform(antennomere2_r_bone) * fold_antennomere2_r); + } - auto mandible_l_bone = *worker_skeleton.get_bone_index("mandible_l"); - auto mandible_r_bone = *worker_skeleton.get_bone_index("mandible_r"); + // Fold waist + gaster + { + const float petiole_fold_angle = math::radians(40.0f); + auto fold_petiole = math::transform::identity(); + fold_petiole.rotation = math::angle_axis(petiole_fold_angle, float3{1, 0, 0}); + + const float postpetiole_fold_angle = math::radians(35.0f); + auto fold_postpetiole = math::transform::identity(); + fold_postpetiole.rotation = math::angle_axis(-postpetiole_fold_angle, float3{1, 0, 0}); + + const float gaster_fold_angle = math::radians(0.0f); + auto fold_gaster = math::transform::identity(); + fold_gaster.rotation = math::angle_axis(-gaster_fold_angle, float3{1, 0, 0}); + + auto petiole_bone = worker_skeleton.get_bone_index("petiole"); + auto postpetiole_bone = worker_skeleton.get_bone_index("postpetiole"); + auto gaster_bone = *worker_skeleton.get_bone_index("gaster"); + + if (petiole_bone) + { + pupal_pose.set_relative_transform(*petiole_bone, worker_rest_pose.get_relative_transform(*petiole_bone) * fold_petiole); + } + + if (postpetiole_bone) + { + pupal_pose.set_relative_transform(*postpetiole_bone, worker_rest_pose.get_relative_transform(*postpetiole_bone) * fold_postpetiole); + } + + pupal_pose.set_relative_transform(gaster_bone, worker_rest_pose.get_relative_transform(gaster_bone) * fold_gaster); + } + + // Invert mesosoma + { + const float mesosoma_invert_angle = math::radians(90.0f); + auto invert_mesosoma = math::transform::identity(); + invert_mesosoma.rotation = math::angle_axis(mesosoma_invert_angle, float3{0, 0, 1}); + + auto mesosoma_bone = *worker_skeleton.get_bone_index("mesosoma"); + pupal_pose.set_relative_transform(mesosoma_bone, invert_mesosoma * worker_rest_pose.get_relative_transform(mesosoma_bone)); + } + + pupal_pose.update(); + + + auto worker_skeletal_mesh = std::make_unique(worker_model); + worker_skeletal_mesh->get_pose() = pupal_pose; - worker_pose.set_relative_transform(mandible_l_bone, worker_rest_pose.get_relative_transform(mandible_l_bone) * open_left_mandible); - worker_pose.set_relative_transform(mandible_r_bone, worker_rest_pose.get_relative_transform(mandible_r_bone) * open_right_mandible); - worker_pose.update(); worker_ant_eid = ctx.entity_registry->create(); transform_component worker_transform_component; @@ -169,7 +385,7 @@ nest_selection_state::nest_selection_state(::game& ctx): worker_body->set_angular_damping(0.5f); worker_body->set_collider(std::move(worker_collider)); - ctx.entity_registry->emplace(worker_ant_eid, std::move(worker_body)); + //ctx.entity_registry->emplace(worker_ant_eid, std::move(worker_body)); // Disable UI color clear ctx.ui_clear_pass->set_cleared_buffers(false, true, false); @@ -225,7 +441,7 @@ nest_selection_state::nest_selection_state(::game& ctx): auto yucca_archetype = ctx.resource_manager->load("yucca-plant-l.ent"); auto yucca_eid = yucca_archetype->create(*ctx.entity_registry); - ::command::warp_to(*ctx.entity_registry, yucca_eid, {0, 0, 30}); + ::command::warp_to(*ctx.entity_registry, yucca_eid, {0, 0, 70}); yucca_archetype = ctx.resource_manager->load("yucca-plant-m.ent"); yucca_eid = yucca_archetype->create(*ctx.entity_registry); @@ -247,10 +463,9 @@ nest_selection_state::nest_selection_state(::game& ctx): cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry); ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {50, 0, 80}); - auto cactus_seed_archetype = ctx.resource_manager->load("barrel-cactus-seed.ent"); - auto cactus_seed_eid = cactus_seed_archetype->create(*ctx.entity_registry); - ::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {10, 0, 10}); - ::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {0, 1, -5}); + // auto cactus_seed_archetype = ctx.resource_manager->load("barrel-cactus-seed.ent"); + // auto cactus_seed_eid = cactus_seed_archetype->create(*ctx.entity_registry); + // ::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {0, 1, -5}); // Create spring @@ -663,7 +878,7 @@ void nest_selection_state::setup_controls() first_person_camera_rig_eid, [&](auto& component) { - component.body->apply_central_impulse({0, 50.0f, 0}); + component.body->apply_central_impulse({0, 5.0f, 0}); } ); } @@ -682,7 +897,7 @@ void nest_selection_state::setup_controls() first_person_camera_rig_eid, [&](auto& component) { - component.body->apply_central_impulse({0, -50.0f, 0}); + component.body->apply_central_impulse({0, -5.0f, 0}); } ); } @@ -701,9 +916,12 @@ void nest_selection_state::setup_controls() const auto& camera_transform = ctx.entity_registry->get(first_person_camera_rig_eid); scene_component projectile_scene; - //projectile_scene.object = std::make_shared(worker_model); + + auto projectile_mesh = std::make_shared(worker_model); + projectile_mesh->get_pose() = *worker_model->get_skeleton().get_pose("pupal"); + projectile_scene.object = projectile_mesh; //projectile_scene.object = std::make_shared(ctx.resource_manager->load("sphere.mdl")); - projectile_scene.object = std::make_shared(ctx.resource_manager->load("cube.mdl")); + //projectile_scene.object = std::make_shared(ctx.resource_manager->load("cube.mdl")); transform_component projectile_transform; projectile_transform.local = camera_transform.world;