bool CExporter::ExportAnimation(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; // show export wizard sheet CAnimationExportSheet sheet("Cal3D Animation Export", m_pInterface->GetMainWnd()); sheet.SetSkeletonCandidate(&skeletonCandidate); sheet.SetAnimationTime(m_pInterface->GetStartFrame(), m_pInterface->GetEndFrame(), m_pInterface->GetCurrentFrame(), m_pInterface->GetFps()); sheet.SetWizardMode(); if(sheet.DoModal() != ID_WIZFINISH) return true; // get the number of selected bone candidates int selectedCount; selectedCount = skeletonCandidate.GetSelectedCount(); if(selectedCount == 0) { SetLastError("No bones selected to export.", __FILE__, __LINE__); return false; } // create the core animation instance cal3d::RefPtr<CalCoreAnimation> coreAnimation = new CalCoreAnimation(); // set the duration of the animation float duration; duration = (float)(sheet.GetEndFrame() - sheet.GetStartFrame()) / (float)m_pInterface->GetFps(); coreAnimation->setDuration(duration); // get bone candidate vector std::vector<CBoneCandidate *>& vectorBoneCandidate = skeletonCandidate.GetVectorBoneCandidate(); size_t boneCandidateId; for(boneCandidateId = 0; boneCandidateId < vectorBoneCandidate.size(); boneCandidateId++) { // get the bone candidate CBoneCandidate *pBoneCandidate; pBoneCandidate = vectorBoneCandidate[boneCandidateId]; // only create tracks for the selected bone candidates if(pBoneCandidate->IsSelected()) { // allocate new core track instance CalCoreTrack *pCoreTrack; pCoreTrack = new CalCoreTrack(); if(pCoreTrack == 0) { theExporter.SetLastError("Memory allocation failed.", __FILE__, __LINE__); theExporter.GetInterface()->StopProgressInfo(); return false; } // create the core track instance if(!pCoreTrack->create()) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); delete pCoreTrack; theExporter.GetInterface()->StopProgressInfo(); return false; } // set the core bone id pCoreTrack->setCoreBoneId(boneCandidateId); // add the core track to the core animation instance if(!coreAnimation->addCoreTrack(pCoreTrack)) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); delete pCoreTrack; theExporter.GetInterface()->StopProgressInfo(); return false; } } } // start the progress info theExporter.GetInterface()->StartProgressInfo("Exporting to animation file..."); // calculate the end frame int endFrame; endFrame = (int)(duration * (float)sheet.GetFps() + 0.5f); // calculate the displaced frame int displacedFrame; displacedFrame = (int)(((float)sheet.GetDisplacement() / (float)m_pInterface->GetFps()) * (float)sheet.GetFps() + 0.5f) % endFrame; // calculate the possible wrap frame int wrapFrame; wrapFrame = (displacedFrame > 0) ? 1 : 0; float wrapTime; wrapTime = 0.0f; int frame; int outputFrame; for(frame = 0, outputFrame = 0; frame <= (endFrame + wrapFrame); frame++) { // update the progress info m_pInterface->SetProgressInfo(int(100.0f * (float)frame / (float)(endFrame + wrapFrame + 1))); // calculate the time in seconds float time; time = (float)sheet.GetStartFrame() / (float)m_pInterface->GetFps() + (float)displacedFrame / (float)sheet.GetFps(); /* DEBUG CString str; str.Format("frame=%d, endframe=%d, disframe=%d, ouputFrame=%d (%f), time=%f\n", frame, endFrame, displacedFrame, outputFrame, (float)outputFrame / (float)sheet.GetFps() + wrapTime, time); OutputDebugString(str); */ for(boneCandidateId = 0; boneCandidateId < vectorBoneCandidate.size(); boneCandidateId++) { // get the bone candidate CBoneCandidate *pBoneCandidate; pBoneCandidate = vectorBoneCandidate[boneCandidateId]; // only export keyframes for the selected bone candidates if(pBoneCandidate->IsSelected()) { // allocate new core keyframe instance CalCoreKeyframe *pCoreKeyframe; pCoreKeyframe = new CalCoreKeyframe(); if(pCoreKeyframe == 0) { theExporter.SetLastError("Memory allocation failed.", __FILE__, __LINE__); theExporter.GetInterface()->StopProgressInfo(); return false; } // create the core keyframe instance if(!pCoreKeyframe->create()) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); delete pCoreKeyframe; theExporter.GetInterface()->StopProgressInfo(); return false; } // set the frame time pCoreKeyframe->setTime((float)outputFrame / (float)sheet.GetFps() + wrapTime); // get the translation and the rotation of the bone candidate CalVector translation; CalQuaternion rotation; skeletonCandidate.GetTranslationAndRotation(boneCandidateId, time, translation, rotation); // set the translation and rotation pCoreKeyframe->setTranslation(translation); pCoreKeyframe->setRotation(rotation); // get the core track for this bone candidate CalCoreTrack *pCoreTrack; pCoreTrack = coreAnimation->getCoreTrack(pBoneCandidate->GetId()); if(pCoreTrack == 0) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); delete pCoreKeyframe; theExporter.GetInterface()->StopProgressInfo(); return false; } // add this core keyframe to the core track pCoreTrack->addCoreKeyframe(pCoreKeyframe); } } // calculate the next displaced frame and its frame time if(wrapFrame > 0) { if(displacedFrame == endFrame) { wrapTime = 0.0001f; displacedFrame = 0; } else { wrapTime = 0.0f; outputFrame++; displacedFrame++; } } else { outputFrame++; displacedFrame++; } } // stop the progress info theExporter.GetInterface()->StopProgressInfo(); // save core animation to the file if(!CalSaver::saveCoreAnimation(strFilename, coreAnimation.get())) { theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__); return false; } return true; }
//------------------------------------------------------------------------------// // 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; }