Browse Source

Add bone add and remove functions to skeleton

master
C. J. Howard 1 year ago
parent
commit
14fa3c7a7c
4 changed files with 88 additions and 16 deletions
  1. +48
    -2
      src/engine/animation/skeleton.cpp
  2. +38
    -12
      src/engine/animation/skeleton.hpp
  3. +1
    -1
      src/engine/render/model.cpp
  4. +1
    -1
      src/game/ant/ant-morphogenesis.cpp

+ 48
- 2
src/engine/animation/skeleton.cpp View File

@ -18,6 +18,7 @@
*/ */
#include <engine/animation/skeleton.hpp> #include <engine/animation/skeleton.hpp>
#include <stdexcept>
skeleton::skeleton(std::size_t bone_count): skeleton::skeleton(std::size_t bone_count):
m_bone_parents(bone_count, 0), m_bone_parents(bone_count, 0),
@ -33,10 +34,55 @@ void skeleton::update_rest_pose()
m_rest_pose.update(); m_rest_pose.update();
} }
void skeleton::set_bone_count(std::size_t bone_count)
bone_index_type skeleton::add_bones(std::size_t bone_count)
{ {
m_bone_parents.resize(bone_count, 0);
const bone_index_type first_bone_index = static_cast<bone_index_type>(m_bone_parents.size());
m_bone_parents.resize(m_bone_parents.size() + bone_count, 0);
m_rest_pose.resize(); m_rest_pose.resize();
return first_bone_index;
}
bone_index_type skeleton::add_bone(hash::fnv1a32_t name)
{
const bone_index_type bone_index = add_bone();
set_bone_name(bone_index, name);
return bone_index;
}
void skeleton::remove_bones()
{
m_bone_parents.clear();
m_bone_map.clear();
m_rest_pose.resize();
}
void skeleton::set_bone_parent(bone_index_type child_index, bone_index_type parent_index)
{
if (child_index < parent_index)
{
throw std::invalid_argument("Child bone index precedes parent bone index");
}
m_bone_parents[child_index] = parent_index;
}
void skeleton::set_bone_name(bone_index_type index, hash::fnv1a32_t name)
{
if (auto i = m_bone_map.find(name); i != m_bone_map.end())
{
if (i->second != index)
{
throw std::invalid_argument("Duplicate bone name");
}
}
else
{
m_bone_map[name] = index;
}
} }
std::optional<bone_index_type> skeleton::get_bone_index(hash::fnv1a32_t name) const std::optional<bone_index_type> skeleton::get_bone_index(hash::fnv1a32_t name) const

+ 38
- 12
src/engine/animation/skeleton.hpp View File

@ -49,11 +49,39 @@ public:
void update_rest_pose(); void update_rest_pose();
/** /**
* Sets the number of bones in the skeleton.
* Add one or more bones to the skeleton.
* *
* @param size Number of bones in the skeleton.
* @param bone_count Number of bones to add.
*
* @return Index of the first added bone.
*/
bone_index_type add_bones(std::size_t bone_count);
/**
* Adds a single bone to the skeleton.
*
* @return Index of the added bone.
*/ */
void set_bone_count(std::size_t size);
inline bone_index_type add_bone()
{
return add_bones(1);
}
/**
* Adds a single named bone to the skeleton.
*
* @param name Name of the bone.
*
* @return Index of the added bone.
*
* @throw std::invalid_argument Duplicate bone name.
*/
bone_index_type add_bone(hash::fnv1a32_t name);
/**
* Removes all bones from the skeleton.
*/
void remove_bones();
/** /**
* Sets the parent of a bone. * Sets the parent of a bone.
@ -61,12 +89,11 @@ public:
* @param child_index Index of the child bone. * @param child_index Index of the child bone.
* @param parent_index Index of the parent bone. * @param parent_index Index of the parent bone.
* *
* @warning The index of a child bone must be greater than the index of its parent. Failure to properly index bones will result in incorrect pose concatenation.
* @warning The index of a child bone must be greater than the index of its parent.
*
* @throw std::invalid_argument Child bone index precedes parent bone index.
*/ */
inline void set_bone_parent(bone_index_type child_index, bone_index_type parent_index)
{
m_bone_parents[child_index] = parent_index;
}
void set_bone_parent(bone_index_type child_index, bone_index_type parent_index);
/** /**
* Sets the transform of a bone, relative to its parent bone. * Sets the transform of a bone, relative to its parent bone.
@ -84,11 +111,10 @@ public:
* *
* @param index Index of a bone. * @param index Index of a bone.
* @param name Name of the bone. * @param name Name of the bone.
*
* @throw std::invalid_argument Duplicate bone name.
*/ */
inline void set_bone_name(bone_index_type index, hash::fnv1a32_t name)
{
m_bone_map[name] = index;
}
void set_bone_name(bone_index_type index, hash::fnv1a32_t name);
/** /**
* Returns the number of bones in the skeleton. * Returns the number of bones in the skeleton.

+ 1
- 1
src/engine/render/model.cpp View File

@ -289,7 +289,7 @@ std::unique_ptr resource_loader::load(::resource_m
ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&bone_count), 1); ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&bone_count), 1);
// Resize skeleton // Resize skeleton
skeleton.set_bone_count(bone_count);
skeleton.add_bones(bone_count);
// Read bones // Read bones
for (std::uint16_t i = 0; i < bone_count; ++i) for (std::uint16_t i = 0; i < bone_count; ++i)

+ 1
- 1
src/game/ant/ant-morphogenesis.cpp View File

@ -277,7 +277,7 @@ void reskin_vertices
void build_ant_skeleton(const ant_phenome& phenome, ::skeleton& skeleton, ant_bone_set& bones) void build_ant_skeleton(const ant_phenome& phenome, ::skeleton& skeleton, ant_bone_set& bones)
{ {
// Allocate bones // Allocate bones
skeleton.set_bone_count(count_ant_skeleton_bones(phenome));
skeleton.add_bones(count_ant_skeleton_bones(phenome));
// Construct ant bone set // Construct ant bone set
bone_index_type bone_index = 0; bone_index_type bone_index = 0;

Loading…
Cancel
Save