Problem with bone weight

Problem with bone weight

Anonymous
Not applicable
1,359 Views
1 Reply
Message 1 of 2

Problem with bone weight

Anonymous
Not applicable

Hi,

I am trying to export a character using the FBX-SDK. I can export the mesh and the bones correctly, but adding weights to the mesh is not working correctly. The file without weights looks like this (Left: Blender, Right: FbxReview):

Blender without weightFbxReview without weight

The file with weights looks like this:

Blender with weightFbxReview with weight

The weights of the vertices are actually correct (if I move a bone the corresponding part of the mesh moves), but the position is off. I suspect it has something to do with SetTransformMatrix or SetTransformLinkMatrix? I also had some problems with the rotation order (had to set it to ZXY) and inherit types (had to set it to RSrs) before, but I don't think that is relevant here since the matrices are set directly (but maybe I am wrong?).

 

My code for adding the weights looks like this:

 

if (obj->hasWeights()) {
	FbxAMatrix meshMatrix = meshNode->EvaluateGlobalTransform();
	FbxSkin* skin = obj->addSkin(manager);
	FbxPose* bindPose = FbxPose::Create(manager, "BindPose");
	bindPose->SetIsBindPose(true);
	std::map<Bone*, std::list<struct VertexWeight>> weights = obj->getVertexWeights();
	for (std::pair<Bone*, std::list<struct VertexWeight>> pair : weights) {
		Bone* curBone = pair.first;
		FbxCluster* cluster = curBone->createCluster(manager);
		for (VertexWeight weight : pair.second) {
			cluster->AddControlPointIndex(weight.vertexIndex, weight.weight);
		}
		FbxNode* boneNode = curBone->getNode();
		FbxAMatrix boneMatrix = boneNode->EvaluateGlobalTransform();
		cluster->SetTransformMatrix(meshMatrix);
		cluster->SetTransformLinkMatrix(boneMatrix);
		skin->AddCluster(cluster);
		FbxNode* curNode = boneNode;
		while (curNode!=nullptr) {
			if(bindPose->Find(curNode)==-1) {
				bindPose->Add(curNode, curNode->EvaluateGlobalTransform());
			}
			curNode = curNode->GetParent();
		}

	}
	
	scene->AddPose(bindPose);
}
FbxSkin * UObject::addSkin(FbxManager * manager)
{
	this->skin = FbxSkin::Create(manager, this->name.c_str());
	((FbxGeometry*)this->node->GetNodeAttribute())->AddDeformer(this->skin);
	return this->skin;
}
FbxCluster * Bone::createCluster(FbxManager * manager)
{
	this->cluster = FbxCluster::Create(manager, this->name.c_str());
	this->cluster->SetLink(this->node);
	this->cluster->SetLinkMode(FbxCluster::ELinkMode::eNormalize);
	return this->cluster;
}

Any ideas or hints are much appreciated.

 

Thanks

0 Likes
Accepted solutions (1)
1,360 Views
1 Reply
Reply (1)
Message 2 of 2

Anonymous
Not applicable
Accepted solution

Turns out that the SDK does not always respect the specified rotation order ... I changed my application to use quaternions and converted the quaternions in the SDK (as described HERE), which seems like the most secure option. The code for the bone weights in my original post did not change.

0 Likes