OpenClonk
StdMeshSkeleton Class Reference

#include <StdMesh.h>

Public Member Functions

 ~StdMeshSkeleton ()
 
const StdMeshBoneGetBone (size_t i) const
 
size_t GetNumBones () const
 
const StdMeshBoneGetBoneByName (const StdStrBuf &name) const
 
const StdMeshAnimationGetAnimationByName (const StdStrBuf &name) const
 
bool IsAnimated () const
 
void MirrorAnimation (const StdMeshAnimation &animation)
 
void InsertAnimation (const StdMeshAnimation &animation)
 
void InsertAnimation (const StdMeshSkeleton &source, const StdMeshAnimation &animation)
 
void PostInit ()
 
std::vector< int > GetMatchingBones (const StdMeshSkeleton &skeleton) const
 
std::vector< const StdMeshAnimation * > GetAnimations () const
 

Friends

class StdMeshSkeletonLoader
 
class StdMeshXML
 
class StdMesh
 
class StdMeshAnimationUpdate
 

Detailed Description

Definition at line 105 of file StdMesh.h.

Constructor & Destructor Documentation

◆ ~StdMeshSkeleton()

StdMeshSkeleton::~StdMeshSkeleton ( )

Definition at line 372 of file StdMesh.cpp.

References StdMeshBone::Index.

373 {
374  for (auto & Bone : Bones)
375  delete Bone;
376 }

Member Function Documentation

◆ GetAnimationByName()

const StdMeshAnimation * StdMeshSkeleton::GetAnimationByName ( const StdStrBuf name) const

Definition at line 396 of file StdMesh.cpp.

Referenced by StdMeshInstanceAnimationNode::CompileFunc(), StdMeshInstance::PlayAnimation(), and StdMeshAnimationUpdate::Update().

397 {
398  StdCopyStrBuf name2(name);
399  std::map<StdCopyStrBuf, StdMeshAnimation>::const_iterator iter = Animations.find(name2);
400  if (iter == Animations.end()) return nullptr;
401  return &iter->second;
402 }
Here is the caller graph for this function:

◆ GetAnimations()

std::vector< const StdMeshAnimation * > StdMeshSkeleton::GetAnimations ( ) const

Definition at line 404 of file StdMesh.cpp.

405 {
406  std::vector<const StdMeshAnimation*> result;
407  result.reserve(Animations.size());
408  for (const auto & Animation : Animations)
409  result.push_back(&Animation.second);
410  return result;
411 }

◆ GetBone()

const StdMeshBone& StdMeshSkeleton::GetBone ( size_t  i) const
inline

Definition at line 116 of file StdMesh.h.

Referenced by StdMeshInstanceAnimationNode::CompileFunc(), GetMatchingBones(), StdMeshLoader::StdMeshXML::LoadBoneAssignments(), StdMeshUpdate::StdMeshUpdate(), and StdMeshInstance::UpdateBoneTransforms().

116 { return *Bones[i]; }
Here is the caller graph for this function:

◆ GetBoneByName()

const StdMeshBone * StdMeshSkeleton::GetBoneByName ( const StdStrBuf name) const

Definition at line 386 of file StdMesh.cpp.

Referenced by StdMeshInstance::AttachMeshImpl(), StdMeshInstanceAnimationNode::CompileFunc(), StdMeshInstance::AttachedMesh::SetChildBone(), StdMeshInstance::AttachedMesh::SetParentBone(), and StdMeshUpdate::Update().

387 {
388  // Lookup parent bone
389  for (auto Bone : Bones)
390  if (Bone->Name == name)
391  return Bone;
392 
393  return nullptr;
394 }
Here is the caller graph for this function:

◆ GetMatchingBones()

std::vector< int > StdMeshSkeleton::GetMatchingBones ( const StdMeshSkeleton skeleton) const

Definition at line 519 of file StdMesh.cpp.

References GetBone(), GetNumBones(), and StdMeshBone::Name.

Referenced by StdMeshInstance::AttachedMesh::ClearPointers(), and InsertAnimation().

520 {
521  std::vector<int> MatchedBoneInParentSkeleton;
522 
523  // find matching bones names in both skeletons
524  for (unsigned int i = 0; i < child_skeleton.GetNumBones(); ++i)
525  {
526  int parent_bone_index = -1; // instantiate with invalid index == no match
527 
528  for (unsigned int j = 0; j < GetNumBones(); ++j)
529  {
530  // start searching at the same index
531  int sample_index = (i + j) % GetNumBones();
532 
533  if (GetBone(sample_index).Name == child_skeleton.GetBone(i).Name)
534  {
535  parent_bone_index = sample_index;
536  break;
537  }
538  }
539 
540  // add valid or invalid mapped index to list of mapped bones
541  MatchedBoneInParentSkeleton.push_back(parent_bone_index);
542  }
543 
544  return MatchedBoneInParentSkeleton;
545 }
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:116
StdCopyStrBuf Name
Definition: StdMesh.h:34
size_t GetNumBones() const
Definition: StdMesh.h:117
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetNumBones()

size_t StdMeshSkeleton::GetNumBones ( ) const
inline

Definition at line 117 of file StdMesh.h.

Referenced by GetMatchingBones(), StdMeshLoader::StdMeshXML::LoadBoneAssignments(), StdMeshUpdate::StdMeshUpdate(), and StdMeshUpdate::Update().

117 { return Bones.size(); }
Here is the caller graph for this function:

◆ InsertAnimation() [1/2]

void StdMeshSkeleton::InsertAnimation ( const StdMeshAnimation animation)

Definition at line 471 of file StdMesh.cpp.

References StdMeshAnimation::Name.

Referenced by StdMeshSkeletonLoader::ResolveIncompleteSkeletons().

472 {
473  assert(Animations.find(animation.Name) == Animations.end());
474 
475  Animations.insert(std::make_pair(animation.Name, animation));
476 }
StdCopyStrBuf Name
Definition: StdMesh.h:97
Here is the caller graph for this function:

◆ InsertAnimation() [2/2]

void StdMeshSkeleton::InsertAnimation ( const StdMeshSkeleton source,
const StdMeshAnimation animation 
)

Definition at line 478 of file StdMesh.cpp.

References GetMatchingBones(), StdMeshAnimation::Length, and StdMeshAnimation::Name.

479 {
480  assert(Animations.find(animation.Name) == Animations.end());
481 
482  // get matching bones from the source
483  std::vector<int> bone_index_source = source.GetMatchingBones(*this);
484 
485  // create a new animation and copy the basic data from the other animation
486  StdMeshAnimation anim;
487  anim.Name = animation.Name;
488  anim.Length = animation.Length;
489  anim.Tracks.resize(GetNumBones());
490  anim.OriginSkeleton = &source;
491 
492  // sort the tracks according to the matched bones
493  for (unsigned int i = 0; i < anim.Tracks.size(); ++i)
494  {
495  if (bone_index_source[i] > -1 && animation.Tracks[bone_index_source[i]] != nullptr)
496  {
497  anim.Tracks[i] = new StdMeshTrack(*animation.Tracks[bone_index_source[i]]);
498  }
499  }
500 
501  // and add it to the map
502  Animations.insert(std::make_pair(animation.Name, anim));
503 }
StdCopyStrBuf Name
Definition: StdMesh.h:97
std::vector< int > GetMatchingBones(const StdMeshSkeleton &skeleton) const
Definition: StdMesh.cpp:519
float Length
Definition: StdMesh.h:98
size_t GetNumBones() const
Definition: StdMesh.h:117
Here is the call graph for this function:

◆ IsAnimated()

bool StdMeshSkeleton::IsAnimated ( ) const
inline

Definition at line 121 of file StdMesh.h.

References StdMeshBone::StdMeshSkeleton.

121 { return !Animations.empty(); }

◆ MirrorAnimation()

void StdMeshSkeleton::MirrorAnimation ( const StdMeshAnimation animation)

Definition at line 413 of file StdMesh.cpp.

References StdStrBuf::Compare_(), StdStrBuf::getData(), StdStrBuf::getLength(), StdMeshBone::GetParent(), StdMeshBone::Index, StdMeshTransformation::Inverse(), StdMeshBone::InverseTransformation, StdMeshBone::Name, StdMeshAnimation::Name, and StdMeshBone::Transformation.

414 {
415  StdCopyStrBuf name(animation.Name);
416 
417  // do nothing if the name cannot be switched from *.L to *.R or vice versa
418  // or if the animation already exists
419  if (!MirrorName(name) || Animations.find(name) != Animations.end())
420  {
421  return;
422  }
423 
424  StdMeshAnimation& new_anim = Animations.insert(std::make_pair(name, animation)).first->second;
425  new_anim.Name = name;
426 
427  // Go through all bones
428  for (unsigned int i = 0; i < GetNumBones(); ++i)
429  {
430  const StdMeshBone& bone = GetBone(i);
431  StdCopyStrBuf other_bone_name(bone.Name);
432  if (MirrorName(other_bone_name))
433  {
434  const StdMeshBone* other_bone = GetBoneByName(other_bone_name);
435  if (!other_bone)
436  throw std::runtime_error(std::string("No counterpart for bone ") + bone.Name.getData() + " found");
437 
438  // Make sure to not swap tracks twice
439  if ((animation.Tracks[i] != nullptr || animation.Tracks[other_bone->Index] != nullptr) &&
440  other_bone->Index > bone.Index)
441  {
442  std::swap(new_anim.Tracks[i], new_anim.Tracks[other_bone->Index]);
443 
445  StdMeshTransformation other_own_trans = other_bone->GetParent()->InverseTransformation * other_bone->Transformation;
446 
447  // Mirror all the keyframes of both tracks
448  if (new_anim.Tracks[i] != nullptr)
449  for (auto & Frame : new_anim.Tracks[i]->Frames)
450  MirrorKeyFrame(Frame.second, own_trans, StdMeshTransformation::Inverse(other_own_trans));
451 
452  if (new_anim.Tracks[other_bone->Index] != nullptr)
453  for (auto & Frame : new_anim.Tracks[other_bone->Index]->Frames)
454  MirrorKeyFrame(Frame.second, other_own_trans, StdMeshTransformation::Inverse(own_trans));
455  }
456  }
457  else if (bone.Name.Compare_(".N", bone.Name.getLength() - 2) != 0)
458  {
459  if (new_anim.Tracks[i] != nullptr)
460  {
461  StdMeshTransformation own_trans = bone.Transformation;
462  if (bone.GetParent()) own_trans = bone.GetParent()->InverseTransformation * bone.Transformation;
463 
464  for (auto & Frame : new_anim.Tracks[i]->Frames)
465  MirrorKeyFrame(Frame.second, own_trans, StdMeshTransformation::Inverse(own_trans));
466  }
467  }
468  }
469 }
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:116
StdCopyStrBuf Name
Definition: StdMesh.h:97
StdMeshTransformation Transformation
Definition: StdMesh.h:37
static StdMeshTransformation Inverse(const StdMeshTransformation &transform)
const StdMeshBone * GetBoneByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:386
const char * getData() const
Definition: StdBuf.h:442
const StdMeshBone * GetParent() const
Definition: StdMesh.h:41
StdCopyStrBuf Name
Definition: StdMesh.h:34
StdMeshTransformation InverseTransformation
Definition: StdMesh.h:39
unsigned int Index
Definition: StdMesh.h:32
int Compare_(const char *pCData, size_t iAt=0) const
Definition: StdBuf.h:484
size_t getLength() const
Definition: StdBuf.h:445
size_t GetNumBones() const
Definition: StdMesh.h:117
Here is the call graph for this function:

◆ PostInit()

void StdMeshSkeleton::PostInit ( )

Definition at line 505 of file StdMesh.cpp.

506 {
507  // Mirror .R and .L animations without counterpart
508  for (auto & Animation : Animations)
509  {
510  // For debugging purposes:
511  // if(iter->second.Name == "Jump")
512  // MirrorAnimation(StdCopyStrBuf("Jump.Mirror"), iter->second);
513 
514  // mirrors only if necessary
515  MirrorAnimation(Animation.second);
516  }
517 }
void MirrorAnimation(const StdMeshAnimation &animation)
Definition: StdMesh.cpp:413

Friends And Related Function Documentation

◆ StdMesh

friend class StdMesh
friend

Definition at line 109 of file StdMesh.h.

◆ StdMeshAnimationUpdate

friend class StdMeshAnimationUpdate
friend

Definition at line 110 of file StdMesh.h.

◆ StdMeshSkeletonLoader

friend class StdMeshSkeletonLoader
friend

Definition at line 107 of file StdMesh.h.

◆ StdMeshXML

friend class StdMeshXML
friend

Definition at line 108 of file StdMesh.h.


The documentation for this class was generated from the following files: