bool CalCoreTrack::getState(float time, CalVector& translation, CalQuaternion& rotation) const { std::vector<CalCoreKeyframe*>::const_iterator iteratorCoreKeyframeBefore; std::vector<CalCoreKeyframe*>::const_iterator iteratorCoreKeyframeAfter; // get the keyframe after the requested time iteratorCoreKeyframeAfter = getUpperBound(time); // check if the time is after the last keyframe if(iteratorCoreKeyframeAfter == m_keyframes.end()) { // return the last keyframe state --iteratorCoreKeyframeAfter; rotation = (*iteratorCoreKeyframeAfter)->getRotation(); translation = (*iteratorCoreKeyframeAfter)->getTranslation(); return true; } // check if the time is before the first keyframe if(iteratorCoreKeyframeAfter == m_keyframes.begin()) { // return the first keyframe state rotation = (*iteratorCoreKeyframeAfter)->getRotation(); translation = (*iteratorCoreKeyframeAfter)->getTranslation(); return true; } // get the keyframe before the requested one iteratorCoreKeyframeBefore = iteratorCoreKeyframeAfter; --iteratorCoreKeyframeBefore; // get the two keyframe pointers CalCoreKeyframe *pCoreKeyframeBefore; pCoreKeyframeBefore = *iteratorCoreKeyframeBefore; CalCoreKeyframe *pCoreKeyframeAfter; pCoreKeyframeAfter = *iteratorCoreKeyframeAfter; // calculate the blending factor between the two keyframe states float blendFactor; blendFactor = (time - pCoreKeyframeBefore->getTime()) / (pCoreKeyframeAfter->getTime() - pCoreKeyframeBefore->getTime()); // blend between the two keyframes translation = pCoreKeyframeBefore->getTranslation(); translation.blend(blendFactor, pCoreKeyframeAfter->getTranslation()); rotation = pCoreKeyframeBefore->getRotation(); rotation.blend(blendFactor, pCoreKeyframeAfter->getRotation()); return true; }
bool CalCoreTrack::getState(float time, CalVector& translation, CalQuaternion& rotation) { rde::sorted_vector<float, CalCoreKeyframe *>::iterator iteratorCoreKeyframeBefore; rde::sorted_vector<float, CalCoreKeyframe *>::iterator iteratorCoreKeyframeAfter; // get the keyframe after the requested time iteratorCoreKeyframeAfter = m_mapCoreKeyframe.upper_bound(time); // check if the time is after the last keyframe if(iteratorCoreKeyframeAfter == m_mapCoreKeyframe.end()) { // return the last keyframe state --iteratorCoreKeyframeAfter; rotation = (iteratorCoreKeyframeAfter->second)->getRotation(); translation = (iteratorCoreKeyframeAfter->second)->getTranslation(); return true; } // check if the time is before the first keyframe if(iteratorCoreKeyframeAfter == m_mapCoreKeyframe.begin()) { // return the first keyframe state rotation = (iteratorCoreKeyframeAfter->second)->getRotation(); translation = (iteratorCoreKeyframeAfter->second)->getTranslation(); return true; } // get the keyframe before the requested one iteratorCoreKeyframeBefore = iteratorCoreKeyframeAfter; --iteratorCoreKeyframeBefore; // get the two keyframe pointers CalCoreKeyframe *pCoreKeyframeBefore; pCoreKeyframeBefore = iteratorCoreKeyframeBefore->second; CalCoreKeyframe *pCoreKeyframeAfter; pCoreKeyframeAfter = iteratorCoreKeyframeAfter->second; // calculate the blending factor between the two keyframe states float blendFactor; blendFactor = (time - pCoreKeyframeBefore->getTime()) / (pCoreKeyframeAfter->getTime() - pCoreKeyframeBefore->getTime()); // blend between the two keyframes translation = pCoreKeyframeBefore->getTranslation(); translation.blend(blendFactor, pCoreKeyframeAfter->getTranslation()); rotation = pCoreKeyframeBefore->getRotation(); rotation.blend(blendFactor, pCoreKeyframeAfter->getRotation()); return true; }
int CMaxAnimationImport::DoImport( const TCHAR* name, ImpInterface* ii, Interface* i, BOOL suppressPrompts) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HWND window = i->GetMAXHWnd(); CFileDialog fileDialog(TRUE, "xsf", 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 0, CWnd::FromHandle(window)); if (fileDialog.DoModal() != IDOK) { return IMPEXP_CANCEL; } CString skeleton = fileDialog.GetPathName(); cal3d::RefPtr<CalCoreSkeleton> skel = CalLoader::loadCoreSkeleton(std::string(skeleton)); if (!skel) { MessageBox( window, "Loading skeleton file failed", "Import Cal3D Animation", MB_OK | MB_ICONERROR); return IMPEXP_FAIL; } cal3d::RefPtr<CalCoreAnimation> anim = CalLoader::loadCoreAnimation(name); if (!anim) { MessageBox( window, "Loading animation file failed", "Import Cal3D Animation", MB_OK | MB_ICONERROR); return IMPEXP_FAIL; } typedef std::list<CalCoreTrack*> CoreTrackList; CoreTrackList& trackList = anim->getListCoreTrack(); for (CoreTrackList::iterator itr = trackList.begin(); itr != trackList.end(); ++itr) { CalCoreTrack* track = *itr; int boneId = track->getCoreBoneId(); CalCoreBone* bone = skel->getCoreBone(boneId); if (!bone) continue; INode* node = i->GetINodeByName(bone->getName().c_str()); if (!node) continue; unsigned kfCount = track->getCoreKeyframeCount(); SuspendAnimate(); AnimateOn(); for (unsigned i = 0; i < kfCount; ++i) { CalCoreKeyframe* kf = track->getCoreKeyframe(i); CalQuaternion kf_q = kf->getRotation(); CalVector kf_v = kf->getTranslation(); TimeValue time = SecToTicks(kf->getTime()); Matrix3 tm; tm.IdentityMatrix(); Quat(kf_q.x, kf_q.y, kf_q.z, kf_q.w).MakeMatrix(tm); tm.SetTrans(Point3(kf_v.x, kf_v.y, kf_v.z)); INode* parent = node->GetParentNode(); if (parent) { tm *= parent->GetNodeTM(time); } node->SetNodeTM(time, tm); } ResumeAnimate(); /* typedef std::map<float, CalCoreKeyframe*> KeyMap; KeyMap& keys = track->getMapCoreKeyframe(); int mapsize = sizeof(keys); int size = keys.size(); int idx = 0; for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) { Point3 p; CalCoreKeyframe* kf = mi->second; p.x = kf->getTranslation().x; p.y = kf->getTranslation().y; p.z = kf->getTranslation().z; pos->SetValue(SecToTicks(mi->first), &p); } */ /* IKeyControl* kc = GetKeyControlInterface(pos); if (!kc) continue; typedef std::map<float, CalCoreKeyframe*> KeyMap; KeyMap& keys = track->getMapCoreKeyframe(); kc->SetNumKeys(keys.size()); int idx = 0; for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) { ITCBPoint3Key key; key.time = SecToTicks(mi->first); key.tens = 0; key.cont = 0; key.bias = 0; key.easeIn = 25.0; key.easeOut = 25.0; key.val.x = mi->second->getTranslation().x; key.val.y = mi->second->getTranslation().y; key.val.z = mi->second->getTranslation().z; kc->SetKey(idx++, &key); } kc->SortKeys(); */ } return IMPEXP_SUCCESS; }