Exemplo n.º 1
0
void FBXSceneEncoder::loadBindShapes(FbxScene* fbxScene)
{
    float m[16];
    const int poseCount = fbxScene->GetPoseCount();
    for (int i = 0; i < poseCount; ++i)
    {
        FbxPose* pose = fbxScene->GetPose(i);
        assert(pose);
        if (pose->IsBindPose() && pose->GetCount() > 0)
        {
            FbxNode* fbxNode = pose->GetNode(0);
            if (fbxNode->GetMesh() != NULL)
            {
                Node* node = _gamePlayFile.getNode(fbxNode->GetName());
                assert(node && node->getModel());

                Model* model = node->getModel();
                if (model && model->getSkin())
                {
                    MeshSkin* skin = model->getSkin();
                    copyMatrix(pose->GetMatrix(0), m);
                    skin->setBindShape(m);
                }
            }
        }
    }
}
void SetBindPose()
{
    assert( g_pFBXScene != nullptr );

    g_BindPoses.clear();
    INT iPoseCount = g_pFBXScene->GetPoseCount();
    for( INT i = 0; i < iPoseCount; ++i )
    {
        auto pPose = g_pFBXScene->GetPose( i );
        INT iNodeCount = pPose->GetCount();
        ExportLog::LogMsg( 4, "Found %spose: \"%s\" with %d nodes", pPose->IsBindPose() ? "bind " : "", pPose->GetName(), iNodeCount );
        for( INT j = 0; j < iNodeCount; ++j )
        {
            auto pPoseNode = pPose->GetNode( j );
            ExportLog::LogMsg( 5, "Pose node %d: %s", j, pPoseNode->GetName() );
        }
        if( pPose->IsBindPose() )
        {
            g_BindPoses.push_back( pPose );
        }
    }
    if( g_BindPoses.empty() )
    {
        if( g_pScene->Settings().bExportAnimations )
        {
            ExportLog::LogWarning( "No valid bind pose found; will export scene using the default pose." );
        }
        return;
    }

    size_t dwPoseCount = g_BindPoses.size();
    for( size_t i = 0; i < dwPoseCount; ++i )
    {
        FbxPose* pPose = g_BindPoses[i];
        INT iNodeCount = pPose->GetCount();
        for( INT j = 0; j < iNodeCount; ++j )
        {
            auto pNode = pPose->GetNode( j );
            auto matNode = pPose->GetMatrix( j );

            PoseMap::iterator iter = g_BindPoseMap.find( pNode );
            if( iter != g_BindPoseMap.end() )
            {
                FbxMatrix matExisting = iter->second;
                if( matExisting != matNode )
                {
                    ExportLog::LogWarning( "Node \"%s\" found in more than one bind pose, with conflicting transforms.", pNode->GetName() );
                }
            }

            g_BindPoseMap[pNode] = matNode;
        }
    }

    ExportLog::LogMsg( 3, "Created bind pose map with %Iu nodes.", g_BindPoseMap.size() );
}
/**
 * Add a bind pose to the scene based on the FbxMesh and skinning settings of the given node
 */
void FFbxExporter::CreateBindPose(FbxNode* MeshRootNode)
{
	if (!MeshRootNode)
	{
		return;
	}

	// In the bind pose, we must store all the link's global matrix at the time of the bind.
	// Plus, we must store all the parent(s) global matrix of a link, even if they are not
	// themselves deforming any model.

	// Create a bind pose with the link list

	FbxArray<FbxNode*> lClusteredFbxNodes;
	int                       i, j;

	if (MeshRootNode->GetNodeAttribute())
	{
		int lSkinCount=0;
		int lClusterCount=0;
		switch (MeshRootNode->GetNodeAttribute()->GetAttributeType())
		{
		case FbxNodeAttribute::eMesh:
		case FbxNodeAttribute::eNurbs:
		case FbxNodeAttribute::ePatch:

			lSkinCount = ((FbxGeometry*)MeshRootNode->GetNodeAttribute())->GetDeformerCount(FbxDeformer::eSkin);
			//Go through all the skins and count them
			//then go through each skin and get their cluster count
			for(i=0; i<lSkinCount; ++i)
			{
				FbxSkin *lSkin=(FbxSkin*)((FbxGeometry*)MeshRootNode->GetNodeAttribute())->GetDeformer(i, FbxDeformer::eSkin);
				lClusterCount+=lSkin->GetClusterCount();
			}
			break;
		}
		//if we found some clusters we must add the node
		if (lClusterCount)
		{
			//Again, go through all the skins get each cluster link and add them
			for (i=0; i<lSkinCount; ++i)
			{
				FbxSkin *lSkin=(FbxSkin*)((FbxGeometry*)MeshRootNode->GetNodeAttribute())->GetDeformer(i, FbxDeformer::eSkin);
				lClusterCount=lSkin->GetClusterCount();
				for (j=0; j<lClusterCount; ++j)
				{
					FbxNode* lClusterNode = lSkin->GetCluster(j)->GetLink();
					AddNodeRecursively(lClusteredFbxNodes, lClusterNode);
				}

			}

			// Add the patch to the pose
			lClusteredFbxNodes.Add(MeshRootNode);
		}
	}

	// Now create a bind pose with the link list
	if (lClusteredFbxNodes.GetCount())
	{
		// A pose must be named. Arbitrarily use the name of the patch node.
		FbxPose* lPose = FbxPose::Create(Scene, MeshRootNode->GetName());

		// default pose type is rest pose, so we need to set the type as bind pose
		lPose->SetIsBindPose(true);

		for (i=0; i<lClusteredFbxNodes.GetCount(); i++)
		{
			FbxNode*  lKFbxNode   = lClusteredFbxNodes.GetAt(i);
			FbxMatrix lBindMatrix = lKFbxNode->EvaluateGlobalTransform();

			lPose->Add(lKFbxNode, lBindMatrix);
		}

		// Add the pose to the scene
		Scene->AddPose(lPose);
	}
}
Exemplo n.º 4
0
void ExportBones(const Value& obj)
{
	const Value& boneName = obj["BoneName"];
	if (boneName.IsNull())
	{
		return;
	}

	//string name = obj["Name"].GetString();

	const Value& parentIndex = obj["ParentIndex"];
	const Value& boneTransform = obj["BoneTransform"];

	fbxBones.resize(boneName.Size());
	for (uint32_t i = 0; i < fbxBones.size(); i++)
	{
		FbxNode* boneNode = FbxNode::Create(pScene, boneName[i].GetString());
		fbxBones[i] = boneNode;
		double x, y, z, w;
		x = boneTransform[i * 7 + 0].GetDouble();
		x = -x;
		y = boneTransform[i * 7 + 1].GetDouble();
		z = boneTransform[i * 7 + 2].GetDouble();
		boneNode->LclTranslation.Set(FbxDouble3(x, y, z));

		x = boneTransform[i * 7 + 3].GetDouble();
		y = boneTransform[i * 7 + 4].GetDouble();
		z = boneTransform[i * 7 + 5].GetDouble();
		w = boneTransform[i * 7 + 6].GetDouble();

		FbxSkeleton* pSkeleton = FbxSkeleton::Create(pScene, boneName[i].GetString());
		int parent = parentIndex[i].GetInt();
		if (parent == -1) {
			pSkeleton->SetSkeletonType(FbxSkeleton::eRoot);
		}
		else {
			pSkeleton->SetSkeletonType(FbxSkeleton::eLimbNode);
			pSkeleton->Size.Set(0.1);
		}

		boneNode->SetNodeAttribute(pSkeleton);
	}

	for (uint32_t i = 0; i < fbxBones.size(); i++) {
		int parent = parentIndex[i].GetInt();
		if (parent == -1) {
			pScene->GetRootNode()->AddChild(fbxBones[i]);
		}
		else {
			fbxBones[parent]->AddChild(fbxBones[i]);
		}
	}

	FbxPose* lPose = FbxPose::Create(pScene, boneName[0].GetString());
	// default pose type is rest pose, so we need to set the type as bind pose
	lPose->SetIsBindPose(true);

	for (uint32_t i = 0; i < fbxBones.size(); i++) {
		FbxNode*  lKFbxNode = fbxBones[i];
		FbxMatrix lBindMatrix = lKFbxNode->EvaluateGlobalTransform();
		lPose->Add(lKFbxNode, lBindMatrix);
	}

	pScene->AddPose(lPose);

}