Esempio n. 1
1
void BlenderSceneExporter::storeSkeletons( TamySkeleton* arrSkeletons, int skeletonsCount )
{
   ResourcesManager& resMgr = TSingleton< ResourcesManager >::getInstance();

   m_exportedSkeletons.clear();
   m_exportedSkeletons.resize( skeletonsCount );

   Matrix boneLocalMtx;
   for ( int skeletonIdx = 0; skeletonIdx < skeletonsCount; ++skeletonIdx )
   {
      const TamySkeleton& exportedSkeleton = arrSkeletons[skeletonIdx];

      FilePath skeletonPath( m_animationsExportDir + exportedSkeleton.name + "." + Skeleton::getExtension() );
      Skeleton* skeleton = resMgr.create< Skeleton >( skeletonPath );
      skeleton->clear();
      m_exportedSkeletons[skeletonIdx] = skeleton;

      // set skeleton bones
      for ( int boneIdx = 0; boneIdx < exportedSkeleton.bonesCount; ++boneIdx )
      {
         const TamyBone& exportedBone = exportedSkeleton.bones[boneIdx];
         
         Matrix boneLocalTransform, invBoneMSTransform;
         if ( exportedBone.parentBoneIdx >= 0 )
         {
            const TamyBone& parentBone = exportedSkeleton.bones[exportedBone.parentBoneIdx];

            parentBone.modelSpaceTransform.applyTo( invBoneMSTransform );
            invBoneMSTransform.invert();

            Matrix boneMSTransform;
            exportedBone.modelSpaceTransform.applyTo( boneMSTransform );

            boneLocalTransform.setMul( boneMSTransform, invBoneMSTransform );
         }
         else
         {
            exportedBone.modelSpaceTransform.applyTo( boneLocalTransform );
         }

         skeleton->addBone( exportedBone.name, boneLocalTransform, exportedBone.parentBoneIdx, exportedBone.boneLength );
      }

      // calculate skeleton's bind pose
      skeleton->buildSkeleton();

      // save the skeleton
      if ( m_exportSettings.saveAnimations )
      {
         skeleton->saveResource();
      }
   }
}
Esempio n. 2
0
	bool Convert(const VfsPath& daeFilename, const VfsPath& pmdFilename, CColladaManager::FileType type)
	{
		// To avoid always loading the DLL when it's usually not going to be
		// used (and to do the same on Linux where delay-loading won't help),
		// and to avoid compile-time dependencies (because it's a minor pain
		// to get all the right libraries to build the COLLADA DLL), we load
		// it dynamically when it is required, instead of using the exported
		// functions and binding at link-time.
		if (! dll.IsLoaded())
		{
			if (! dll.LoadDLL())
			{
				LOGERROR(L"Failed to load COLLADA conversion DLL");
				return false;
			}

			try
			{
				dll.LoadSymbol("set_logger", set_logger);
				dll.LoadSymbol("set_skeleton_definitions", set_skeleton_definitions);
				dll.LoadSymbol("convert_dae_to_pmd", convert_dae_to_pmd);
				dll.LoadSymbol("convert_dae_to_psa", convert_dae_to_psa);
			}
			catch (PSERROR_DllLoader&)
			{
				LOGERROR(L"Failed to load symbols from COLLADA conversion DLL");
				dll.Unload();
				return false;
			}

			VfsPath skeletonPath("art/skeletons/skeletons.xml");

			// Set the filename for the logger to report
			set_logger(ColladaLog, static_cast<void*>(&skeletonPath));

			CVFSFile skeletonFile;
			if (skeletonFile.Load(g_VFS, skeletonPath) != PSRETURN_OK)
			{
				LOGERROR(L"Failed to read skeleton definitions");
				dll.Unload();
				return false;
			}

			int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize());
			if (ok < 0)
			{
				LOGERROR(L"Failed to load skeleton definitions");
				dll.Unload();
				return false;
			}

			// TODO: the cached PMD/PSA files should probably be invalidated when
			// the skeleton definition file is changed, else people will get confused
			// as to why it's not picking up their changes
		}

		// Set the filename for the logger to report
		set_logger(ColladaLog, const_cast<void*>(static_cast<const void*>(&daeFilename)));

		// We need to null-terminate the buffer, so do it (possibly inefficiently)
		// by converting to a CStr
		CStr daeData;
		{
			CVFSFile daeFile;
			if (daeFile.Load(g_VFS, daeFilename) != PSRETURN_OK)
				return false;
			daeData = daeFile.GetAsString();
		}

		// Do the conversion into a memory buffer
		WriteBuffer writeBuffer;
		switch (type)
		{
		case CColladaManager::PMD: convert_dae_to_pmd(daeData.c_str(), ColladaOutput, &writeBuffer); break;
		case CColladaManager::PSA: convert_dae_to_psa(daeData.c_str(), ColladaOutput, &writeBuffer); break;
		}

		// don't create zero-length files (as happens in test_invalid_dae when
		// we deliberately pass invalid XML data) because the VFS caching
		// logic warns when asked to load such.
		if (writeBuffer.Size())
		{
			Status ret = g_VFS->CreateFile(pmdFilename, writeBuffer.Data(), writeBuffer.Size());
			ENSURE(ret == INFO::OK);
		}

		return true;
	}