bool CEditableObject::LoadBoneData(IReader& F) { BoneVec load_bones; int count=0; IReader* R; while(0!=(R=F.open_chunk(count++))) { CBone* nBone = xr_new<CBone>(); load_bones.push_back(nBone); nBone->LoadData(*R); Msg("loaded bone [%s]", nBone->Name().c_str()); } bool bRes = true; // load bones if (!load_bones.empty()){ for (BoneIt b_it=m_Bones.begin(); b_it!=m_Bones.end(); b_it++){ CBone* B = *b_it; BoneIt n_it = std::find_if(load_bones.begin(),load_bones.end(),fBoneNameEQ(B->Name())); if (n_it!=load_bones.end()) { B->CopyData (*n_it); }else{ ELog.Msg (mtError,"Can't find bone: '%s'.",*(*b_it)->Name()); bRes = false; // break; } } for (BoneIt n_it=load_bones.begin(); n_it!=load_bones.end(); n_it++) xr_delete(*n_it); load_bones.clear(); }else{ ELog.Msg (mtError,"Empty bone list."); bRes = false; } // load bone part if (F.find_chunk(EOBJ_CHUNK_BONEPARTS2)){ shared_str buf; m_BoneParts.resize(F.r_u32()); for (BPIt bp_it=m_BoneParts.begin(); bp_it!=m_BoneParts.end(); bp_it++){ F.r_stringZ (buf); bp_it->alias=buf; bp_it->bones.resize (F.r_u32()); for (RStringVecIt s_it=bp_it->bones.begin(); s_it!=bp_it->bones.end(); s_it++) F.r_stringZ (*s_it); } if (!m_BoneParts.empty()&&!VerifyBoneParts()) ELog.Msg (mtError,"Invalid bone parts. Found missing or duplicate bone."); }else{ ELog.Msg (mtError,"Can't load bone parts. Invalid version."); } return bRes; }
void CEditableObject::PrepareBones() { if (m_Bones.empty())return; CBone* PARENT = 0; // clear empty parent for (BoneIt b_it=m_Bones.begin(); b_it!=m_Bones.end(); b_it++){ BoneIt parent = std::find_if(m_Bones.begin(),m_Bones.end(),fBoneNameEQ((*b_it)->ParentName())); if (parent==m_Bones.end()){ (*b_it)->SetParentName(""); VERIFY2 (0==PARENT,"Invalid object. Have more than 1 parent."); PARENT = *b_it; }else{ BoneIt parent = std::find_if(m_Bones.begin(),m_Bones.end(),fBoneNameEQ((*b_it)->ParentName())); (*b_it)->parent = (parent==m_Bones.end())?0:*parent; } } // sort by name std::sort(m_Bones.begin(),m_Bones.end(),pred_sort_B); // fill children for (b_it=m_Bones.begin(); b_it!=m_Bones.end(); b_it++){ BoneIt parent = std::find_if(m_Bones.begin(),m_Bones.end(),fBoneNameEQ((*b_it)->ParentName())); if (parent!=m_Bones.end()) (*parent)->children.push_back(*b_it); } // manual sort u32 b_cnt = m_Bones.size(); m_Bones.clear (); fill_bones_by_parent(m_Bones,PARENT); VERIFY (b_cnt==m_Bones.size()); // update SelfID for (b_it=m_Bones.begin(); b_it!=m_Bones.end(); b_it++) (*b_it)->SelfID = b_it-m_Bones.begin(); VERIFY(0==m_Bones.front()->parent); /* for (b_it=m_Bones.begin(); b_it!=m_Bones.end(); b_it++) Msg("%20s - %20s",(*b_it)->Name().c_str(),(*b_it)->ParentName().c_str()); */ CalculateBindPose (); }
BoneIt CEditableObject::FindBoneByNameIt(const char* name) { return std::find_if(m_Bones.begin(),m_Bones.end(),fBoneNameEQ(name)); }