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(); CalCoreSkeletonPtr skel = CalLoader::loadCoreSkeleton(std::string(skeleton)); if (!skel) { MessageBox( window, "Loading skeleton file failed", "Import Cal3D Animation", MB_OK | MB_ICONERROR); return IMPEXP_FAIL; } CalCoreAnimationPtr anim = CalLoader::loadCoreAnimation(name); if (!anim) { MessageBox( window, "Loading animation file failed", "Import Cal3D Animation", MB_OK | MB_ICONERROR); return IMPEXP_FAIL; } // Get the pose information in the animation const std::vector<CalTransform>& poses = anim->getPoses(); unsigned int num_poses = poses.size() / anim->getTrackCount(); // Calculate the time_per_frame incorrectly since the duration for animations // is stored incorrectly. float time_per_frame = anim->getDuration() / num_poses; // Import each track for (unsigned track_id = 0; track_id < anim->getTrackCount(); ++track_id) { // Get the core bone mapped to the animation int bone_id = anim->getBoneAssignment(track_id); CalCoreBone* bone = skel->getCoreBone(bone_id); if (!bone) continue; // Get the max node for the bone INode* node = i->GetINodeByName(bone->getName().c_str()); if (!node) continue; SuspendAnimate(); AnimateOn(); // Add each pose keyframe in the track float keyframe_time = 0.0f; for (unsigned keyframe_index = 0; keyframe_index < num_poses; ++keyframe_index) { // Get the keyframe data const CalTransform& pose_coord_sys = poses[(keyframe_index * anim->getTrackCount()) + track_id]; const CalVector &kf_v = pose_coord_sys.getTranslation(); const CalQuaternion &kf_q = pose_coord_sys.getRotation(); TimeValue time = SecToTicks(keyframe_time); // Convert to Max math 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)); // Convert the transform to world space INode* parent = node->GetParentNode(); if (parent) { tm *= parent->GetNodeTM(time); } // Set the new transform on the node node->SetNodeTM(time, tm); keyframe_time += time_per_frame; } 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; }
//------------------------------------------------------------------------------// // Export the skeleton from a Maxscript call --// //------------------------------------------------------------------------------// bool CMaxInterface::ExportSkeletonFromMaxscriptCall(const std::string& strFilename, bool bShowUI) { // build a skeleton candidate CSkeletonCandidate skeletonCandidate; if(!skeletonCandidate.CreateFromInterfaceFromMaxScriptCall()) return false; //Does the user wants to see the UI and select the bones himself ? if (bShowUI) { // show export wizard sheet CSkeletonExportSheet sheet(_T("Cal3D Skeleton Export"), GetMainWnd()); sheet.SetSkeletonCandidate(&skeletonCandidate); sheet.SetWizardMode(); if(sheet.DoModal() != ID_WIZFINISH) return true; } // build the selected ids of the bone candidates int selectedCount = skeletonCandidate.BuildSelectedId(); if(selectedCount == 0) { theExporter.SetLastError("No bones selected to export.", __FILE__, __LINE__); return false; } // create the core skeleton instance CalCoreSkeletonPtr coreSkeleton = new CalCoreSkeleton; // get bone candidate vector std::vector<CBoneCandidate *>& vectorBoneCandidate = skeletonCandidate.GetVectorBoneCandidate(); // start the progress info StartProgressInfo("Exporting to skeleton file..."); size_t boneCandidateId; int selectedId; for(boneCandidateId = 0, selectedId = 0; boneCandidateId < vectorBoneCandidate.size(); boneCandidateId++) { // get the bone candidate CBoneCandidate *pBoneCandidate; pBoneCandidate = vectorBoneCandidate[boneCandidateId]; // only export selected bone candidates if(pBoneCandidate->IsSelected()) { // update the progress info SetProgressInfo(int(100.0f * (selectedId + 1) / selectedCount)); selectedId++; // allocate new core bone instance CalCoreBone *pCoreBone = new CalCoreBone(pBoneCandidate->GetNode()->GetName()); // get the parent id of the bone candidate int parentId; parentId = skeletonCandidate.GetParentSelectedId(boneCandidateId); // set the parentId pCoreBone->setParentId(parentId); // get the translation and the rotation of the bone candidate CalVector translation; CalQuaternion rotation; skeletonCandidate.GetTranslationAndRotation(boneCandidateId, -1.0f, translation, rotation); // set the translation and rotation pCoreBone->setTranslation(translation); pCoreBone->setRotation(rotation); // get the bone space translation and the rotation of the bone candidate CalVector translationBoneSpace; CalQuaternion rotationBoneSpace; skeletonCandidate.GetTranslationAndRotationBoneSpace(boneCandidateId, -1.0f, translationBoneSpace, rotationBoneSpace); // set the bone space translation and rotation pCoreBone->setTranslationBoneSpace(translationBoneSpace); pCoreBone->setRotationBoneSpace(rotationBoneSpace); // set the core skeleton of the core bone instance pCoreBone->setCoreSkeleton(coreSkeleton.get()); // add the core bone to the core skeleton instance int boneId; boneId = coreSkeleton->addCoreBone(pCoreBone); // adjust child list of parent bone if(parentId != -1) { // get parent core bone CalCoreBone *pParentCoreBone; pParentCoreBone = coreSkeleton->getCoreBone(parentId); if(pParentCoreBone == 0) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); delete pCoreBone; StopProgressInfo(); return false; } // add this core bone to the child list of the parent bone pParentCoreBone->addChildId(boneId); } } } // stop the progress info StopProgressInfo(); // save core skeleton to the file if(!CalSaver::saveCoreSkeleton(strFilename, coreSkeleton.get())) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); return false; } return true; }
bool CExporter::ExportSkeleton(const std::string& strFilename) { // check if a valid interface is set if(m_pInterface == 0) { SetLastError("Invalid handle.", __FILE__, __LINE__); return false; } // build a skeleton candidate CSkeletonCandidate skeletonCandidate; if(!skeletonCandidate.CreateFromInterface()) return false; // show export wizard sheet CSkeletonExportSheet sheet("Cal3D Skeleton Export", m_pInterface->GetMainWnd()); sheet.SetSkeletonCandidate(&skeletonCandidate); sheet.SetWizardMode(); if(sheet.DoModal() != ID_WIZFINISH) return true; // build the selected ids of the bone candidates int selectedCount = skeletonCandidate.BuildSelectedId(); if(selectedCount == 0) { SetLastError("No bones selected to export.", __FILE__, __LINE__); return false; } // create the core skeleton instance CalCoreSkeletonPtr coreSkeleton = new CalCoreSkeleton; // get bone candidate vector std::vector<CBoneCandidate *> vectorBoneCandidate = skeletonCandidate.GetVectorBoneCandidate(); // start the progress info m_pInterface->StartProgressInfo("Exporting to skeleton file..."); size_t boneCandidateId; int selectedId; for(boneCandidateId = 0, selectedId = 0; boneCandidateId < vectorBoneCandidate.size(); boneCandidateId++) { // get the bone candidate CBoneCandidate *pBoneCandidate = vectorBoneCandidate[boneCandidateId]; // only export selected bone candidates if(pBoneCandidate->IsSelected()) { // update the progress info m_pInterface->SetProgressInfo(int(100.0f * (selectedId + 1) / selectedCount)); selectedId++; // allocate new core bone instance CalCoreBone *pCoreBone = new CalCoreBone(pBoneCandidate->GetNode()->GetName()); // get the parent id of the bone candidate int parentId = skeletonCandidate.GetParentSelectedId(boneCandidateId); // set the parentId pCoreBone->setParentId(parentId); // get the translation and the rotation of the bone candidate CalVector translation; CalQuaternion rotation; skeletonCandidate.GetTranslationAndRotation(boneCandidateId, -1.0f, translation, rotation); // set the translation and rotation pCoreBone->setTranslation(translation); pCoreBone->setRotation(rotation); // get the bone space translation and the rotation of the bone candidate CalVector translationBoneSpace; CalQuaternion rotationBoneSpace; skeletonCandidate.GetTranslationAndRotationBoneSpace(boneCandidateId, -1.0f, translationBoneSpace, rotationBoneSpace); // set the bone space translation and rotation pCoreBone->setTranslationBoneSpace(translationBoneSpace); pCoreBone->setRotationBoneSpace(rotationBoneSpace); // set the core skeleton of the core bone instance pCoreBone->setCoreSkeleton(coreSkeleton.get()); // add the core bone to the core skeleton instance int boneId; boneId = coreSkeleton->addCoreBone(pCoreBone); // adjust child list of parent bone if(parentId != -1) { // get parent core bone CalCoreBone *pParentCoreBone; pParentCoreBone = coreSkeleton->getCoreBone(parentId); if(pParentCoreBone == 0) { SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); delete pCoreBone; m_pInterface->StopProgressInfo(); return false; } // add this core bone to the child list of the parent bone pParentCoreBone->addChildId(boneId); } } } // stop the progress info m_pInterface->StopProgressInfo(); // save core skeleton to the file if(!CalSaver::saveCoreSkeleton(strFilename, coreSkeleton.get())) { SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); return false; } HKEY hk; LONG lret=RegCreateKey(HKEY_CURRENT_USER, "Software\\Cal3D\\Exporter", &hk); if(lret==ERROR_SUCCESS && NULL!=hk) { lret=RegSetValueEx(hk,"skeleton",NULL,REG_SZ,(unsigned char *)strFilename.c_str() ,strFilename.length()); RegCloseKey(hk); } return true; }