Jump to content

  • Log In with Google      Sign In   
  • Create Account

How to debug an fx file


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
26 replies to this topic

#21 Buckeye   Crossbones+   -  Reputation: 6386

Like
1Likes
Like

Posted 21 March 2014 - 08:07 AM

In my article, take a look at the section A Slight Diversion from the Initialization Process.

 

Each bone's animation transform (I think they're the NodeTransformation in the article you referenced) orients the bone LOCALLY. "Locally" means (e.g.) a hand bone rotates about it's own Y-axis a little during an animation. That rotation about the bone's Y-axis is to take place wherever the bone is in the world. Maybe the arm is raised into the air or off to one side. The hand bone moves with the arm, but the rotation is still to take place about the bone's Y-axis, not the world Y-axis.

 

So, if the vertices around the character's hand are to be rotated about the hand bone's Y-axis, that rotation needs to take place relative to the hand bone, not the world Y-axis. See the illustration in the section of the article I linked. The vertex positions in the mesh around the hand are in world(*) space. The offset matrix transforms the vertex from world space to bone space. The animation (scale-rotate-translate) then takes place in bone space. Then the combined animation transforms move the vertex back to world space for rendering.

 

(*) that's really root-node space. I'm calling it "world" to give you a better visualization.


Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


Sponsor:

#22 Saad Manzur   Members   -  Reputation: 203

Like
0Likes
Like

Posted 21 March 2014 - 12:36 PM


In my article, take a look at the section A Slight Diversion from the Initialization Process.

 

Buck, from what I read from the article. Here is what I learned. Correct me if I am wrong....
 

1. I am given the offset matrix by Assimp [which you calculated]

2. And the transformation matrix is given by Assimp's aiNode structure's mTransformation.(Assimp's documentation : "The transformation relative to the node's parent.")

3. Now all I have to do is recursively calculate the transformation matrix for each bone by multiplying it with it's parent transformation.

4. And to render it I have to multiply the offset matrix with each bone's transformation matrix...

 

I just want to create the bind pose first.



#23 Buckeye   Crossbones+   -  Reputation: 6386

Like
0Likes
Like

Posted 21 March 2014 - 01:42 PM

As mentioned previously, I'm not familiar with Assimp and how they implement the node hierarchy. The best I can do is say "It sounds like it."


Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


#24 Saad Manzur   Members   -  Reputation: 203

Like
0Likes
Like

Posted 22 March 2014 - 02:35 PM

Buck, 

I wrote this function to calculate the transformation matrices. It is similar to the tutorial of the blog. And also I did some research in Assimp. It seems mTransformation "is local in relation to its parent node" . So I am guessing it transforms mesh space to bone space. I have to multiply it with each of its children. And the offset matrices are pre calculated. Here is the function:

 

void Bones::UpdateNode(const aiNode *pNode, const XMFLOAT4X4 parentMatrix) //Bone Index, Parent Matrix (Transformation)
{
	const char *name = pNode->mName.C_Str();
	XMFLOAT4X4 temp;
	AItoXM(pNode->mTransformation, temp);
	XMMATRIX NodeTransformation = XMLoadFloat4x4(&temp);

	XMMATRIX finalTransform = NodeTransformation * XMLoadFloat4x4(&parentMatrix);

	if (mBoneInfoMap.find(name) != mBoneInfoMap.end())
	{
		int boneID = mBoneInfoMap[name];
		XMMATRIX temp2 = XMLoadFloat4x4(&m_GlobalInverseTransform) * finalTransform * XMLoadFloat4x4(&mBoneInfo[boneID].offsetMatrix);
		XMStoreFloat4x4(&mBoneInfo[boneID].Transform, temp2);
	}

	XMFLOAT4X4 temp3;
	XMStoreFloat4x4(&temp3, finalTransform);

	for (int i = 0; i < pNode->mNumChildren; i++)
	{
		UpdateNode(pNode->mChildren[i], temp3);
	}
}

The author of the tutorial passed the scene's RootNode and an identity matrix . But if I do that the mesh is distorted. Do I have to pass the RootNode of the scene ?


Edited by Saad Manzur, 23 March 2014 - 02:24 AM.


#25 Buckeye   Crossbones+   -  Reputation: 6386

Like
0Likes
Like

Posted 22 March 2014 - 03:57 PM


Do I have to pass the RootNode of the scene ?

Did you try that?


Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


#26 Saad Manzur   Members   -  Reputation: 203

Like
0Likes
Like

Posted 23 March 2014 - 02:24 AM

Yes I tried that still getting massively distorted mesh. I tried Icebreaker's method. It should have worked. Is there any specific ordering to multiply this matrices. I tried multiplying the opposite order still no good.

Assimp says : mOffsetMatrix = the matrix transforming from mesh space to bone space, also called inverse bind pose transform 

                      mTransform = a node's transformation matrix in relation to it's parent node

 

So, this information and does my code match ? 



#27 Buckeye   Crossbones+   -  Reputation: 6386

Like
0Likes
Like

Posted 23 March 2014 - 07:02 AM


So, this information and does my code match ?

I can't tell you. It sounds like you're just trying this, that and the other, hoping to stumble on something that works. With hundreds of lines of code and complex data, that's probably not going to be a good approach.

 

At some point, you need to understand what each line of code should do, and, more importantly, determine whether it does what it's supposed to do.

 

The approach I personally prefer is to follow the data. Pick a point in your code and look at the data. Verify that it's correct. If it's not, pick a point earlier in the process. Keep moving earlier in the process until you find correct data.

 

Then move on to the next step. Pick a line of code in the process where you think everything preceding it is correct, likely the point where you just found good values. If that line of code looks right, then you have to check the data that's coming into that line, to see if the data is correct. If the data is correct, then verify the data gets manipulated by the code the way it should by checking that the data that comes out of the manipulation is correct.

 

Most programmers know the code better than the data. They can write a line such as: MatrixInverse( Matrix invMat, Matrix inputMat ). But, to know that it's the correct code, someone in the project has to know what a matrix is, what the inverse of a matrix is, and whether (at that point in the code) the inverse of a matrix is needed. If the code is correct, but the results are not correct, someone in the project has to look at the actual inputMat and determine if the data is correct.

 

If that "someone in the project" is you, you have to be able to do those things.


Edited by Buckeye, 23 March 2014 - 07:03 AM.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS