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 107 of file StdMesh.h.

Constructor & Destructor Documentation

StdMeshSkeleton::~StdMeshSkeleton ( )

Definition at line 374 of file StdMesh.cpp.

375 {
376  for (unsigned int i = 0; i < Bones.size(); ++i)
377  delete Bones[i];
378 }

Member Function Documentation

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

Definition at line 398 of file StdMesh.cpp.

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

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 }

Here is the caller graph for this function:

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 (std::map<StdCopyStrBuf, StdMeshAnimation>::const_iterator iter = Animations.begin(); iter != Animations.end(); ++iter)
411  result.push_back(&iter->second);
412  return result;
413 }
const StdMeshBone& StdMeshSkeleton::GetBone ( size_t  i) const
inline

Definition at line 118 of file StdMesh.h.

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

118 { return *Bones[i]; }

Here is the caller graph for this function:

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

Definition at line 388 of file StdMesh.cpp.

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

389 {
390  // Lookup parent bone
391  for (unsigned int i = 0; i < Bones.size(); ++i)
392  if (Bones[i]->Name == name)
393  return Bones[i];
394 
395  return nullptr;
396 }

Here is the caller graph for this function:

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

Definition at line 521 of file StdMesh.cpp.

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

Referenced by InsertAnimation().

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 }
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:118
StdCopyStrBuf Name
Definition: StdMesh.h:36
size_t GetNumBones() const
Definition: StdMesh.h:119

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 119 of file StdMesh.h.

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

119 { return Bones.size(); }

Here is the caller graph for this function:

void StdMeshSkeleton::InsertAnimation ( const StdMeshAnimation animation)

Definition at line 473 of file StdMesh.cpp.

References StdMeshAnimation::Name.

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

Definition at line 480 of file StdMesh.cpp.

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

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 }
StdCopyStrBuf Name
Definition: StdMesh.h:99
std::vector< int > GetMatchingBones(const StdMeshSkeleton &skeleton) const
Definition: StdMesh.cpp:521
size_t GetNumBones() const
Definition: StdMesh.h:119

Here is the call graph for this function:

bool StdMeshSkeleton::IsAnimated ( ) const
inline

Definition at line 123 of file StdMesh.h.

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

Definition at line 415 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().

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 
446  StdMeshTransformation own_trans = bone.GetParent()->InverseTransformation * bone.Transformation;
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 (std::map<float, StdMeshKeyFrame>::iterator iter = new_anim.Tracks[i]->Frames.begin(); iter != new_anim.Tracks[i]->Frames.end(); ++iter)
452  MirrorKeyFrame(iter->second, own_trans, StdMeshTransformation::Inverse(other_own_trans));
453 
454  if (new_anim.Tracks[other_bone->Index] != nullptr)
455  for (std::map<float, StdMeshKeyFrame>::iterator iter = new_anim.Tracks[other_bone->Index]->Frames.begin(); iter != new_anim.Tracks[other_bone->Index]->Frames.end(); ++iter)
456  MirrorKeyFrame(iter->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 (std::map<float, StdMeshKeyFrame>::iterator iter = new_anim.Tracks[i]->Frames.begin(); iter != new_anim.Tracks[i]->Frames.end(); ++iter)
467  MirrorKeyFrame(iter->second, own_trans, StdMeshTransformation::Inverse(own_trans));
468  }
469  }
470  }
471 }
const char * getData() const
Definition: StdBuf.h:450
StdCopyStrBuf Name
Definition: StdMesh.h:99
StdMeshTransformation Transformation
Definition: StdMesh.h:39
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:118
const StdMeshBone * GetBoneByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:388
StdCopyStrBuf Name
Definition: StdMesh.h:36
StdMeshTransformation InverseTransformation
Definition: StdMesh.h:41
unsigned int Index
Definition: StdMesh.h:34
size_t getLength() const
Definition: StdBuf.h:453
size_t GetNumBones() const
Definition: StdMesh.h:119
const StdMeshBone * GetParent() const
Definition: StdMesh.h:43
int Compare_(const char *pCData, size_t iAt=0) const
Definition: StdBuf.h:492

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshSkeleton::PostInit ( )

Definition at line 507 of file StdMesh.cpp.

References MirrorAnimation().

508 {
509  // Mirror .R and .L animations without counterpart
510  for (std::map<StdCopyStrBuf, StdMeshAnimation>::iterator iter = Animations.begin(); iter != Animations.end(); ++iter)
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(iter->second);
518  }
519 }
void MirrorAnimation(const StdMeshAnimation &animation)
Definition: StdMesh.cpp:415

Here is the call graph for this function:

Friends And Related Function Documentation

friend class StdMesh
friend

Definition at line 111 of file StdMesh.h.

friend class StdMeshAnimationUpdate
friend

Definition at line 112 of file StdMesh.h.

friend class StdMeshSkeletonLoader
friend

Definition at line 109 of file StdMesh.h.

friend class StdMeshXML
friend

Definition at line 110 of file StdMesh.h.


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