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 374 of file StdMesh.cpp.

375 {
376  for (auto & Bone : Bones)
377  delete Bone;
378 }

Member Function Documentation

◆ GetAnimationByName()

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

Definition at line 398 of file StdMesh.cpp.

399 {
400  StdCopyStrBuf name2(name);
401  std::map<StdCopyStrBuf, StdMeshAnimation>::const_iterator iter = Animations.find(name2);
402  if (iter == Animations.end()) return nullptr;
403  return &iter->second;
404 }

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

Here is the caller graph for this function:

◆ GetAnimations()

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

Definition at line 406 of file StdMesh.cpp.

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

◆ GetBone()

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

Definition at line 116 of file StdMesh.h.

116 { return *Bones[i]; }

Referenced by StdMeshInstanceAnimationNode::CompileFunc(), GetMatchingBones(), MirrorAnimation(), StdMeshUpdate::StdMeshUpdate(), and StdMeshInstance::UpdateBoneTransforms().

Here is the caller graph for this function:

◆ GetBoneByName()

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

Definition at line 388 of file StdMesh.cpp.

389 {
390  // Lookup parent bone
391  for (const auto & Bone : Bones)
392  if (Bone->Name == name)
393  return Bone;
394 
395  return nullptr;
396 }

Referenced by StdMeshInstance::AttachMeshImpl(), StdMeshInstanceAnimationNode::CompileFunc(), and MirrorAnimation().

Here is the caller graph for this function:

◆ GetMatchingBones()

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

Definition at line 521 of file StdMesh.cpp.

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

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

Referenced by InsertAnimation().

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.

117 { return Bones.size(); }

Referenced by GetMatchingBones(), InsertAnimation(), MirrorAnimation(), and StdMeshUpdate::Update().

Here is the caller graph for this function:

◆ InsertAnimation() [1/2]

void StdMeshSkeleton::InsertAnimation ( const StdMeshAnimation animation)

Definition at line 473 of file StdMesh.cpp.

474 {
475  assert(Animations.find(animation.Name) == Animations.end());
476 
477  Animations.insert(std::make_pair(animation.Name, animation));
478 }
StdCopyStrBuf Name
Definition: StdMesh.h:97

References StdMeshAnimation::Name.

◆ InsertAnimation() [2/2]

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

Definition at line 480 of file StdMesh.cpp.

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

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

Here is the call graph for this function:

◆ IsAnimated()

bool StdMeshSkeleton::IsAnimated ( ) const
inline

Definition at line 121 of file StdMesh.h.

121 { return !Animations.empty(); }

◆ MirrorAnimation()

void StdMeshSkeleton::MirrorAnimation ( const StdMeshAnimation animation)

Definition at line 415 of file StdMesh.cpp.

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

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

Referenced by PostInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PostInit()

void StdMeshSkeleton::PostInit ( )

Definition at line 507 of file StdMesh.cpp.

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

References MirrorAnimation().

Here is the call graph for this function:

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: