XNA 4.0 Update Download

Topics: Developer Forum, Project Management Forum, User Forum
Dec 10, 2010 at 6:27 AM

With permission from dastle, I am posting a link to the XNA 4.0 updated version of his library and the dwarf tutorial sample also. Please try to run it on your system and let me know if it works or if you encounter problems. I have tried it on my home computer and my xbox360 and both work for me.

 Download: http://www.lowpoly3d.net/downloads/XNAanimationXbox360.rar

 Enjoy and please give me you feedback.

 Mark

Dec 11, 2010 at 6:49 AM

Tested on my machine (Windows 7) and Xbox360. no problems here. Ran just fine.

I only received a warning message about flat.x not having keyframes (but that's what it's suppose to do.) 

great work guys.

has anyone planned any new features?

 

Dec 11, 2010 at 7:34 AM

I am working on enabling shader support so you don't have to be stuck with only using the BasicEffect that is used by default now. I had it working in the 3.1 version, but seem to be having trouble getting everything working in the 4.0 project. If I get it working, I will post the updated source. Glad to hear it worked on your system and keep me informed if any problems arrise.

Coordinator
Dec 13, 2010 at 9:39 AM

Cool! I'll take a look at it tomorrow.

Coordinator
Dec 14, 2010 at 1:59 AM
Edited Dec 14, 2010 at 2:00 AM

I'm downloading the latest XNA game studio right now :)

I may have to wait until tomorrow for the download to complete.

Things have certainly changed a lot since I last worked on this project!

Dec 14, 2010 at 5:46 AM

I just changed the skinFX.fx file to get some of the effects I wanted, but unfortunately I can not get normalmapping to work yet. The tangent and binormals are not working. I did get diffuse, specular and shine working and it helps make the model look a little more like I want. If you want to try it, here is the new skinFX.fx file and the settings I used in effect parameters. dastle, if you know how to get normalmapping to work, please let me know, maybe the problem is just the dwarf model. I will try another model to see if has the same errors?

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

//    Added new Effect Parameters

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

// Replace the old effects with your custom shader
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    BasicEffect oldEffect = (BasicEffect)part.Effect;
                    Effect newEffect = myEffect.Clone();
                    newEffect.Parameters["Texture"].SetValue(oldEffect.Texture);

                    newEffect.Parameters["LightColor"].SetValue(new Vector4(0.3f, 0.3f, 0.3f, 1.0f));
                    newEffect.Parameters["AmbientLightColor"].SetValue(new Vector4(1.25f, 1.25f, 1.25f, 1.0f));
                    newEffect.Parameters["Shininess"].SetValue(0.6f);
                    newEffect.Parameters["SpecularPower"].SetValue(0.4f);

                    newEffect.Parameters["View"].SetValue(view);
                    newEffect.Parameters["Projection"].SetValue(projection);

                    part.Effect = newEffect;           
                    oldEffect.Dispose();
                }
            }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

//    The new skinFX.fx file 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

float4x4 MatrixPalette[56];
float4x4 World;
float4x4 View;
float4x4 Projection;

// ***** Light properties *****
float3 LightPosition;
float4 LightColor;
float4 AmbientLightColor;
// ****************************

// ***** material properties *****

// output from phong specular will be scaled by this amount
float Shininess;

// specular exponent from phong lighting model.  controls the "tightness" of
// specular highlights.
float SpecularPower;
// *******************************

texture2D Texture;
sampler2D DiffuseTextureSampler = sampler_state
{
    Texture = ;
    MinFilter = linear;
    MagFilter = linear;
    MipFilter = linear;
};

struct VS_INPUT
{
    float4 position            : POSITION0;
    float2 texCoord            : TEXCOORD0;
    float3 normal              : NORMAL0;    
       
    // These are the indices (4 of them) that index the bones that affect
	// this vertex.  The indices refer to the MatrixPalette.
	half4 indices : BLENDINDICES0;
	// These are the weights (4 of them) that determine how much each bone
	// affects this vertex.
	float4 weights : BLENDWEIGHT0;
};

// output from the vertex shader, and input to the pixel shader.
// lightDirection and viewDirection are in world space.
// NOTE: even though the tangentToWorld matrix is only marked 
// with TEXCOORD3, it will actually take TEXCOORD3, 4, and 5.
struct VS_OUTPUT
{
    float4 position            : POSITION0;
    float2 texCoord            : TEXCOORD0;
    float3 lightDirection    : TEXCOORD1;
    float3 viewDirection    : TEXCOORD2;
    float3x3 tangentToWorld    : TEXCOORD3;
};

// This is the output from our skinning method
struct SKIN_OUTPUT
{
    float4 position;
    float4 normal;
};

   // This method takes in a vertex and applies the bone transforms to it.
    SKIN_OUTPUT Skin4( const VS_INPUT input)
    {
        SKIN_OUTPUT output = (SKIN_OUTPUT)0;
        // Since the weights need to add up to one, store 1.0 - (sum of the weights)
        float lastWeight = 1.0;
        float weight = 0;
        // Apply the transforms for the first 3 weights
        for (int i = 0; i < 3; ++i)
        {
            weight = input.weights[i];
            lastWeight -= weight;
            output.position     += mul( input.position, MatrixPalette[input.indices[i]]) * weight;
            output.normal       += mul( input.normal, MatrixPalette[input.indices[i]]) * weight;
        }
        // Apply the transform for the last weight
        output.position     += mul( input.position, MatrixPalette[input.indices[3]])*lastWeight;
        output.normal       += mul( input.normal, MatrixPalette[input.indices[3]])*lastWeight;
       
        return output;
    };
    
VS_OUTPUT VertexShaderFunction( VS_INPUT input )
{
    VS_OUTPUT output;
    
    // Calculate the skinned position
        SKIN_OUTPUT skin = Skin4(input);
        
    // transform the position into projection space
    float4 worldSpacePos = mul(input.position, World);
   
    float4x4 WorldViewProjection = mul(World,mul(View,Projection));

    output.position = mul(skin.position, WorldViewProjection);    
    
    // similarly, calculate the view direction, from the eye to the surface.  not
    // normalized, in world space.
    float3 eyePosition = mul(-View._m30_m31_m32, transpose(View));    
    output.viewDirection = worldSpacePos - eyePosition;    
    output.lightDirection = worldSpacePos + LightPosition.xyz - eyePosition;
    
    // calculate tangent space to world space matrix using the world space tangent,
    // binormal, and normal as basis vectors.  the pixel shader will normalize these
    // in case the world matrix has scaling.
    output.tangentToWorld[0] = mul(input.normal,    World);
    output.tangentToWorld[1] = mul(input.normal,    World);
    output.tangentToWorld[2] = mul(input.normal,    World);
    
    // pass the texture coordinate through without additional processing
    output.texCoord = input.texCoord;
    
    return output;
}

float4 PixelShaderFunction( VS_OUTPUT input ) : COLOR0
{    
    // look up the normal from the normal map, and transform from tangent space
    // into world space using the matrix created above.  normalize the result
    // in case the matrix contains scaling.
    float3 normalFromMap = tex2D(DiffuseTextureSampler, input.texCoord);
    normalFromMap = mul(normalFromMap, input.tangentToWorld);
    normalFromMap = normalize(normalFromMap);
    
    // clean up our inputs a bit
    input.viewDirection = normalize(input.viewDirection);
    input.lightDirection = normalize(input.lightDirection);    
   
    // use the normal we looked up to do phong diffuse style lighting.    
    float nDotL = max(dot(input.lightDirection * normalFromMap, input.lightDirection * normalFromMap), input.lightDirection * normalFromMap);
    float4 diffuse = LightColor * nDotL;
    
    // use phong to calculate specular highlights: reflect the incoming light
    // vector off the normal, and use a dot product to see how "similar"
    // the reflected vector is to the view vector.    
    float3 reflectedLight = reflect(input.lightDirection, normalFromMap);
    float rDotV = max(dot(reflectedLight, input.viewDirection), input.viewDirection - normalFromMap);
    float4 specular = Shininess * LightColor * pow(rDotV, SpecularPower);
    
    float4 diffuseTexture = tex2D(DiffuseTextureSampler, input.texCoord);
    
    // return the combined result.
    return diffuseTexture * (diffuse + AmbientLightColor) - specular;
}

Technique NormalMapping
{
    Pass Go
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
Coordinator
Dec 18, 2010 at 6:14 AM
Thanks for posting this. I'll look into the fx problem when I have some more time after the weekend.
Feb 3, 2011 at 10:52 PM

Hey!

I got the library for XNA 4.0 and it works great so far.  Already started playing with it (and animations from 3drt.com)

Question:

Does it have to use the SkinFX file. I couldn't seem to get it to work without it.

Or..

I'd really like to use fog in my game (it's with zombies) can the skinfx file be updated?

Also.. i wouldn't mind making a small donation as this library saved me hours of work.

-Carmine

Feb 6, 2011 at 11:29 PM

Hi carmine,

     I only upgraded this project to work in XNA 4.0, dastle was the original creator, so he would probably be able to answer your questions better than me, but as far as I know, Yes you need to use the SkinFX file or a custom fx file that handles the skinning info and bone weights needed to animate your model. As far as using fog, you would have to ask dastle how to do that as I am not sure if you can or not without modifying the fx file. Good luck and hope you get it to work the way you want.

Feb 18, 2011 at 8:39 PM

Two questions:

1) Will this port support Windows Phone 7?   The WP7 doesn't allow custom shaders.  How much does this library depend on them?

2) Anyone know of other options for WP7 XNA animation?

Thanks, Doug Mair

Mar 25, 2011 at 8:53 AM
Edited Mar 26, 2011 at 10:57 AM

Hi.

 

Using this sample code I've managed to get animations working in my XNA 4 game - so thanks! 

I have a question about the dwarfmodel.x file, though: I'm trying to edit it to change the mesh (swap the axe for a pickaxe). What editor should I use? I've tried importing into Blender 2.49 but I get an "IndexError: list index out of range" error on the console. Blender 2.56 doesn't seem to have any option yet to import .x's. I'm trying to work with the original .ms3d now but it's all such an uphill battle! Exporting from Blender 2.49 it seems to have lost its textures and the XNA loader crashes with it anyway.

Why does modelling have to be so hard? Everything else about XNA is so easy!

Anyone have any tips or suggestions?

 

Thanks

- Phil

Mar 29, 2011 at 6:26 PM
Edited Mar 29, 2011 at 6:30 PM

In case anyone Google's this thread and is interested, I found an answer (with carmine's help!)

The dwarf and axe are two different MeshParts governed by two different Effect objects. Therefore there are a number of different ways one can draw the dwarf without his axe - the first hack occurring to me being to give the axe a nonsensical View matrix: It worked. Haven't settled on a final solution yet as MeshPart is part of the XNA framework and so my first thought of adding a .Visible attribute to MeshPart isn't doable. I'll probably add an array of Booleans to ModelAnimator to tell it to ignore drawing individual MeshParts/Effects. Either that or add an extra Visible parameter to SkinFX to ignore the Axe.

Secondly, drawing an alternate object in place of the axe is extremely easy; Simply follow the instructions as per drawing a collision cube in the tutorial. No more than a couple of lines of code.

Apr 1, 2011 at 11:11 PM

Hey... i got a problem. When im importing FBX models, i got no errors finding the animations in the file, but i got a problem with a bonePose thing.

 

        /// <summary>
        /// Gets a BonePose object.
        /// </summary>
        /// <param name="boneName">The name of the bone for which the BonePose
        /// will be returned.</param>
        /// <returns>The BonePose associated with the bone name.</returns>
        public BonePose this[string boneName]
        {
            get { return boneDict[boneName]; }
        }

 

The error is:            The given key was not present in the dictionary.

Anyone got any ideas? i would really appreciate your help on this matter.

Apr 2, 2011 at 1:51 AM

Don't really have any ideas.

Is the FBX file ASCII? If not, can you make it so so you can look inside? Can you see the bone in the file when you do? Is it a case sensitive lookup?

Dunno much about fbx myself, been sticking to x.

Apr 2, 2011 at 2:59 AM
Edited Apr 2, 2011 at 3:04 AM

thing is, the library recognizes all the bones. I added a writeLine to a file, so i can see the bones in there. So it`s ok, it works so far.

 

    public class BonePoseCollection 
        : System.Collections.ObjectModel.ReadOnlyCollection<BonePose>
    {
        
        // A dictionary for quick access to bone poses based on bone name
        private Dictionary<string, BonePose> boneDict 
            = new Dictionary<string, BonePose>();

        // This class should not be externally instantiated
        internal BonePoseCollection(IList<BonePose> anims)
            :
            base(anims)
        {
            
            for (int i = 0; i < anims.Count; i++)
            {
                string boneName = anims[i].Name;
                if (boneName != null && boneName != "" && !boneDict.ContainsKey(boneName))
                {
                    boneDict.Add(boneName, anims[i]);
                    System.IO.StreamWriter file = new System.IO.StreamWriter("d:\\test.txt", true);
                    file.WriteLine(boneName);

                    file.Close();

                }
            }
        }

 

 

 

This is the part that`s not working.

 

 

        public BonePose this[string boneName]
        {
            get { return boneDict[boneName]; }
        }

 

I didnt wrote it, elasto, Mash or Dastle did it. I tried with both ASCII and binary files. Same thing. Yea, opened `em in notepad, and i can see the bones.

And a bit offtopic, is there any .fbx to .x converter? i couldnt find anything.

 

 

EDIT:   crap, nevermind. It works. I didnt notice the weapon BonePose in the main file. Commented it out and it worked. Sorry to bother you, guys.