Пример #1
0
void CFbxExporter::Export( const String& assetFolder, const String& resourceFolder, const String& filePath )
{
	log::Log log(new log::DefaultMessages(), -1);
	FbxConv conv(&log);

	Settings settings;
	settings.flipV = false;
	settings.packColors = false;
	settings.verbose = true;
	settings.maxNodePartBonesCount = 120;
	settings.maxVertexBonesCount = 4;
	settings.maxVertexCount = INT_MAX; //   (1 << 15) - 1;
	settings.maxIndexCount = INT_MAX; // (1 << 15) - 1;
	settings.outType = FILETYPE_AUTO;
	settings.inType = FILETYPE_FBX;
	settings.inFile = std::string( (assetFolder + filePath).c_str() );

	modeldata::Model *model = new modeldata::Model();
	if (!conv.load(&settings, model))
	{
		return;
	}

	conv.info(model);

	CSkeleton* pLastSkeleton = nullptr;

	for (Node* node : model->nodes)
	{
		CSkeleton* pSkeleton = new CSkeleton();
		ParseModelNode( node, *pSkeleton, "" );
		pSkeleton->ComputeGlobalPose(pSkeleton->m_localBindPose, pSkeleton->m_globalBindPose);


		String skeletonPath = resourceFolder + filePath.get_path_base() + filePath.get_path_name() + ".skel";
		gVars->pFileSystem->CreateFileDir( skeletonPath );
		pSkeleton->SaveToFile( skeletonPath );

		if ( pLastSkeleton != nullptr )
		{
			delete pLastSkeleton;
		}

		pLastSkeleton = pSkeleton;
	}


	for (Animation* ani : model->animations)
	{
		CAnimation* pAnimation = new CAnimation();

		for (NodeAnimation* nodeAnim : ani->nodeAnimations)
		{
			int idx = pLastSkeleton->m_boneNameToIndex[nodeAnim->node->id.c_str()];
			if (idx < 0)
				continue;

			const std::vector< Keyframe* >& keyframes = nodeAnim->keyframes;

			Transform* trackKeys = new Transform[ keyframes.size() ];

			for (size_t iKey = 0; iKey < keyframes.size(); ++iKey)
			{
				const Keyframe& k = *(keyframes[ iKey ]);

				Transform transf;
				transf.rotation = Quat(k.rotation[3], k.rotation[0], k.rotation[1], k.rotation[2]);

				if (transf.rotation.w < 0.0f)
				{
					transf.rotation = -1.0f * transf.rotation;
				}

				transf.position = Vec3(k.translation[0], k.translation[1], k.translation[2]);
				transf.scale = Vec3(k.scale[0], k.scale[1], k.scale[2]);

				transf = pLastSkeleton->m_localBindPose.m_boneTransforms[idx].GetInverse() * transf;
				
				if (String(nodeAnim->node->id.c_str()).Contains("twist"))
				{
					transf = Transform();
				}

				trackKeys[ iKey ] = transf;
			}

			pAnimation->AddAnimationTack( new CAnimationTrack( CAnimationTrack::eKFF_Transform, trackKeys, keyframes.size() ), idx );
		}

		String animPath = resourceFolder + filePath.get_path_base() + filePath.get_path_name() + ".anim";
		gVars->pFileSystem->CreateFileDir(animPath);
		pAnimation->SaveToFile(animPath);
		delete pAnimation;
	}

	if (pLastSkeleton != nullptr)
	{
		delete pLastSkeleton;
	}


	for (Mesh* mesh : model->meshes)
	{
		CMeshHelper mh;
		size_t vertexCount = mesh->vertexCount();
		size_t vertexFloatCount = mesh->vertexSize;
		mh.m_positionArray.reserve(vertexCount);
		mh.m_normalArray.reserve(vertexCount);

		size_t attCount = mesh->attributes.length();
		for (size_t att = 0; att < attCount; ++att)
		{
			size_t idx = mesh->attributes.get(att);


			unsigned int offset = 0;
			for (unsigned int i = 0; i < idx; i++)
				if (mesh->attributes.has(i))
					offset += (unsigned int)ATTRIBUTE_SIZE(i);
		

			switch (idx)
			{
			case ATTRIBUTE_POSITION:
			{
				for (size_t i = 0; i < vertexCount; ++i)
				{
					mh.AddPosition(*(Vec3*)(&mesh->vertices[vertexFloatCount * i]));



				}
				break;
			}
			case ATTRIBUTE_NORMAL:
			{
		
					for (size_t i = 0; i < vertexCount; ++i)
					{
						mh.AddNormal(*(Vec3*)(&mesh->vertices[offset + vertexFloatCount * i]));
					}
				break;
			}
			case ATTRIBUTE_BLENDWEIGHT0:
			case ATTRIBUTE_BLENDWEIGHT1:
			case ATTRIBUTE_BLENDWEIGHT2:
			case ATTRIBUTE_BLENDWEIGHT3:
			case ATTRIBUTE_BLENDWEIGHT4:
			case ATTRIBUTE_BLENDWEIGHT5:
			case ATTRIBUTE_BLENDWEIGHT6:
			case ATTRIBUTE_BLENDWEIGHT7:
			{
				size_t attributeIndex = idx - (size_t)ATTRIBUTE_BLENDWEIGHT0;
				for (size_t i = 0; i < vertexCount; ++i)
				{
					mh.AddBlendWeight( attributeIndex, *((SVertexBlendWeight*)(&mesh->vertices[offset + vertexFloatCount * i])) );
				}
				break;
			}
			}

		}

		for (MeshPart* meshPart : mesh->parts)
		{
			mh.AddMeshPart();
			CMeshPartHelper* part = mh.GetMeshPart(mh.m_meshParts.size()-1);

			for (unsigned short indice : meshPart->indices)
			{
				part->AddIndex(indice);
			}
		}

		String meshPath = resourceFolder + filePath.get_path_base() + filePath.get_path_name() + ".msh";
		
		gVars->pFileSystem->CreateFileDir( meshPath );
		mh.SaveToFile( meshPath );
	}
}