OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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 ( )

Definition at line 372 of file StdMesh.cpp.

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

Member Function Documentation

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

Definition at line 396 of file StdMesh.cpp.

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

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:

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 }
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(), MirrorAnimation(), StdMeshUpdate::StdMeshUpdate(), and StdMeshInstance::UpdateBoneTransforms().

116 { return *Bones[i]; }

Here is the caller graph for this function:

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

Definition at line 386 of file StdMesh.cpp.

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

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:

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 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:

size_t StdMeshSkeleton::GetNumBones ( ) const
inline

Definition at line 117 of file StdMesh.h.

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

117 { return Bones.size(); }

Here is the caller graph for this function:

void StdMeshSkeleton::InsertAnimation ( const StdMeshAnimation animation)

Definition at line 471 of file StdMesh.cpp.

References StdMeshAnimation::Name.

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
void StdMeshSkeleton::InsertAnimation ( const StdMeshSkeleton source,
const StdMeshAnimation animation 
)

Definition at line 478 of file StdMesh.cpp.

References GetMatchingBones(), GetNumBones(), 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
float Length
Definition: StdMesh.h:98
std::vector< int > GetMatchingBones(const StdMeshSkeleton &skeleton) const
Definition: StdMesh.cpp:519
size_t GetNumBones() const
Definition: StdMesh.h:117

Here is the call graph for this function:

bool StdMeshSkeleton::IsAnimated ( ) const
inline

Definition at line 121 of file StdMesh.h.

121 { return !Animations.empty(); }
void StdMeshSkeleton::MirrorAnimation ( const StdMeshAnimation animation)

Definition at line 413 of file StdMesh.cpp.

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

Referenced by PostInit().

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 
444  StdMeshTransformation own_trans = bone.GetParent()->InverseTransformation * bone.Transformation;
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 char * getData() const
Definition: StdBuf.h:442
StdCopyStrBuf Name
Definition: StdMesh.h:97
StdMeshTransformation Transformation
Definition: StdMesh.h:37
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:116
const StdMeshBone * GetBoneByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:386
StdCopyStrBuf Name
Definition: StdMesh.h:34
StdMeshTransformation InverseTransformation
Definition: StdMesh.h:39
unsigned int Index
Definition: StdMesh.h:32
size_t getLength() const
Definition: StdBuf.h:445
size_t GetNumBones() const
Definition: StdMesh.h:117
const StdMeshBone * GetParent() const
Definition: StdMesh.h:41
int Compare_(const char *pCData, size_t iAt=0) const
Definition: StdBuf.h:484

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshSkeleton::PostInit ( )

Definition at line 505 of file StdMesh.cpp.

References MirrorAnimation().

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

Here is the call graph for this function:

Friends And Related Function Documentation

friend class StdMesh
friend

Definition at line 109 of file StdMesh.h.

friend class StdMeshAnimationUpdate
friend

Definition at line 110 of file StdMesh.h.

friend class StdMeshSkeletonLoader
friend

Definition at line 107 of file StdMesh.h.

friend class StdMeshXML
friend

Definition at line 108 of file StdMesh.h.


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