Jump to content

  • Log In with Google      Sign In   
  • Create Account


Skinned Model Screwy


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
5 replies to this topic

#1 Drakken255   Members   -  Reputation: 173

Like
0Likes
Like

Posted 30 July 2012 - 06:42 AM

Hello all,

I'm sure everyone is tired of my questions, but I have one more before I can really get to work on my project. For those of you who don't know, I am creating a basic XNA recreation of Minecraft. My current problem is that my "Steve" model, which is skinned with an armature using vertex groups to deform, is showing up disfigured beyond all reason. I am using a custom shader with skinning imported from the SkinnedEffect from the StockEffects example. I'm sure the effect itself works fine and that my model's groups and weights are the problem. But, to be sure, I will post both.

Pictures:
Posted Image
Posted Image

My Custom Shader:

//VertexShader
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
	VertexShaderOutput output;
	Skin(input, NumBones);
	float4x4 worldViewProj = mul(mul(World, View), Projection);
	output.Position = mul(input.Position, worldViewProj);
	float4 normal = mul(input.Normal, WorldInverseTranspose);
	float lightIntensity = dot(normal, DiffuseLightDirection);
	output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
	output.Color.a = 1;
	output.TextureCoordinate = input.TextureCoordinate;
	return output;
}

//Skin() Method
void Skin(inout VertexShaderInput input, uniform int boneCount)
{
	float4x4 skinning = 0;
	[unroll]
	for (int i = 0; i < boneCount; i++)
	{
		skinning += Bones[input.Indices[i]] * input.Weights[i];
	}
	input.Position = mul(input.Position, skinning);
}

And my Steve model is here in .blend format. The version of Blender I use is 2.6. Pay no attention to the corner-looking piece. That's just there for size comparison when I built him. I export to .fbx with only the mesh and armature selected. No options are selected other than "Export Selected" and "Apply Modifiers". Smoothing is off, Forward is -Z Forward and Up is Y Up. Again, I think the problem is the vertex groups and wights. Everything deforms properly in Blender, but not in XNA.

Edited by Drakken255, 31 July 2012 - 07:58 AM.


Sponsor:

#2 Waaayoff   Members   -  Reputation: 686

Like
0Likes
Like

Posted 31 July 2012 - 02:46 PM

The shader looks fine so the problem must be with the model itself. Or with how you're loading it.

1) Try to force the model into a specific pose in the shader to make sure the problem isn't due to the bone matrices. (Maybe you need to transpose them?)

2) Make sure the weights add up to 1

3) Ouput the bone indices as the vertex colour to see if they're correct.
"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "

#3 Drakken255   Members   -  Reputation: 173

Like
0Likes
Like

Posted 31 July 2012 - 03:54 PM

Sorry, little too much for my knowledge. I tried to make sure that all vertices had only one group assigned to it. I think I messed my bones up or something. Could you please look at my model file? Also, I'll post the rendering code:

foreach (ModelMesh mesh in steve.Meshes)
{
    foreach (ModelMeshPart part in mesh.MeshParts)
    {
        part.Effect = minecraftEffect;
    }
}
foreach (ModelMesh mesh in steve.Meshes)
{
    //Tried to move the LegLeft bone
    //steveTransforms[13] *= Matrix.CreateRotationX(MathHelper.ToRadians(1f));

    //Rotates the whole model.
    //steveTransforms[mesh.ParentBone.Index] *= Matrix.CreateRotationY(MathHelper.ToRadians(1f));
    foreach (Effect effect in mesh.Effects)
    {
        effect.Parameters["Bones"].SetValue(steveTransforms);
        effect.Parameters["NumBones"].SetValue(steve.Bones.Count);
        effect.Parameters["WorldInverseTranspose"].SetValue(Matrix.Transpose(Matrix.Invert(mesh.ParentBone.Transform)));
        effect.Parameters["BaseTexture"].SetValue(steveTexture);
        effect.Parameters["World"].SetValue(steveTransforms[mesh.ParentBone.Index]);
         effect.Parameters["View"].SetValue(view);
         effect.Parameters["Projection"].SetValue(projection);
    }
    mesh.Draw();
}

I just changed setting the parameter "Bones" to steveRelTransforms, which uses CopyBoneTransformsTo instead of CopyAbsoluteBoneTransformsTo, and I got this:

Posted Image

#4 quiSHADgho   Members   -  Reputation: 325

Like
0Likes
Like

Posted 01 August 2012 - 01:12 AM

I have looked into your blend file and it seemed quiet right to me. But i didnt found some animations so I suppose you build the transform matrices at runtime. Maybe you need to change them because of the hierachical structure of the armature? So you dont pass the world transform rather than a bone transform matrix in relation to the parent bone up to the root bone. Just a thought I dont know if it applies here.

#5 Drakken255   Members   -  Reputation: 173

Like
0Likes
Like

Posted 01 August 2012 - 02:25 AM

Yes, I am building the matrices at runtime. I had just thought that the bones were being translated relative to the world rather than their parent bone, but that's not the problem... I guess it's the way I'm building the transform matrices. Code:

steveTransforms = new Matrix[steve.Bones.Count];
steveRelTransforms = new Matrix[steve.Bones.Count];

//I originally used this, but it failed. Now I've been using steveRelTransforms.
steve.CopyAbsoluteBoneTransformsTo(steveTransforms);

//Atempt at transforming relative to parents.
steveRelTransforms[steve.Bones["Spine"].Index] = steve.Bones["Spine"].Transform;
steveRelTransforms[steve.Bones["Neck"].Index] *= steve.Bones["Spine"].Transform;
steveRelTransforms[steve.Bones["Head"].Index] *= steve.Bones["Head"].Transform;

steveRelTransforms[steve.Bones["ShoulderLeft"].Index] *= steve.Bones["Spine"].Transform;
steveRelTransforms[steve.Bones["ShoulderRight"].Index] *= steve.Bones["Spine"].Transform;
steveRelTransforms[steve.Bones["ArmLeft"].Index] *= steve.Bones["ShoulderLeft"].Transform;
steveRelTransforms[steve.Bones["ArmRight"].Index] *= steve.Bones["ShoulderRight"].Transform;

steveRelTransforms[steve.Bones["HipLeft"].Index] *= steve.Bones["Spine"].Transform;
steveRelTransforms[steve.Bones["HipRight"].Index] *= steve.Bones["Spine"].Transform;
steveRelTransforms[steve.Bones["LegLeft"].Index] *= steve.Bones["HipLeft"].Transform;
steveRelTransforms[steve.Bones["LegRight"].Index] *= steve.Bones["HipRight"].Transform;


EDIT: On a side note, when I loaded Steve in the XNA Model Viewer at Codeplex It looked perfectly fine until I pressed the Animation Play button. Steve then proceeded to break once again...

Edited by Drakken255, 01 August 2012 - 02:36 AM.


#6 Drakken255   Members   -  Reputation: 173

Like
0Likes
Like

Posted 01 August 2012 - 07:53 AM

I may have fixed the problem... At first, while exporting my Block model, I had thought that drawing with depth was acting screwy because of two options in Blender's FBX Export script: XNA Rotate Hack, and XNA Strict Options. Thus, I did not select these all the times I exported Steve. Re-enabling these seems to have solved the problem. Of course, I will still have to figure out rotation thanks to the enabling of these options disabling rotation from Blender axes to XNA axes.




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