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;
}
Exemple #3
0
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;
}