DarthCoder

Hi,

I'm trying to create a rotate(float pitch,float yaw,float roll) function for my entity class, (The camera one works fine) but despite it working sort of, the model locks up at certain angles(I.e becomes very stiff and hard to rotate, like gimble lock but worse)

Here's the function in question

[code]

public void Rotate(Vector3 Rotation)

{

Matrix m1 = Matrix.CreateRotationX(MathHelper.ToRadians(Rotation.X));

Matrix m2 = Matrix.CreateRotationY(MathHelper.ToRadians(Rotation.Y));

Matrix m3 = Matrix.CreateRotationZ(MathHelper.ToRadians(Rotation.Z));

LocalRotation = m2 * m3 * m1;

 

Update();

}

[/code]

 

I've tried every order possible, doesn't make any difference I can notice.

What I want to achieve is this, and forgive the poor explination.

Imagine the model in question was a human head. if you rotate on the yaw, the left turns left right. even if you are looking up, yaw should still turn the head. Your head does not tilt, it turns left. or another way of putting it, the gun shown in a fps. it's rotation should MATCH the camera's rotation. But in my case, the model wobbles around, locks up.Yet, if i remove two axis, and just try one, it works perfectly. I.e i can rotate just on the pitch axis, or yaw, but not together.

 

Here's my simple shader I use to render the model in case it's something there. IT's a edited version of Hazy Mind's shader, the edit adding support for a model matrix as well as the camera matrix.

[code]

float4x4 WorldViewProject;

float4x4 LocalMatrix;

sampler TextureSampler;

struct VS_INPUT {

float4 Position : POSITION0;

float2 Texcoord : TEXCOORD0;

};

struct VS_OUTPUT {

float4 Position : POSITION0;

float2 Texcoord : TEXCOORD0;

};

VS_OUTPUT Transform(VS_INPUT Input) {

VS_OUTPUT Output;

float4 vp = mul(Input.Position,LocalMatrix);

Output.Position = mul(vp, WorldViewProject);

Output.Texcoord = Input.Texcoord;

return Output;

}

struct PS_INPUT {

float2 Texcoord : TEXCOORD0;

};

float4 Texture(PS_INPUT Input) : COLOR0 {

return tex2D(TextureSampler, Input.Texcoord);

};

technique TransformTexture {

pass P0 {

VertexShader = compile vs_3_0 Transform();

PixelShader = compile ps_3_0 Texture();

}

}

[/code]

I've tried passing a local matrix rather than world and results are identical. the object is positioned at 0,0,0 in the world, so it's unlikely to be because it's off or rotating around another point in space rather than it's direct centre.

 I've only been using xna for a week so i'm guessing it's just a newbie mistake, but i would be very grateful if you could help, totally stuck until i can fix this.

 Thanks.

 



Re: XNA Framework Rotating an entity problems - (Not camera)

DarthCoder

Definitely sure it's something other than the multiplication now.

I ported the matrix multiplication table over from my gl engine(Where i know for sure it works without a hitch) and result is identical to using dx's matrix multiply.

here's my code just in case though. Any ideas anyone This is really annoying.

public static Matrix Multiply(Matrix m1, Matrix m2)

{

Matrix mat = new Matrix();

float[,] ma1 = new float[4, 4];

float[,] ma2 = new float[4, 4];

m1 = FillMat(m1, ma1);

m2 = FillMat(m2, ma2);

float[,] ma3 = new float[4, 4];

float sum = 0;

int row = 0, col = 0;

for (row = 0; row < 4; row++)

{

for (col = 0; col < 4; col++)

{

for (int r = 0; r < 4; r++)

{

float a, b, c;

a = ma1[r, col];

b = ma2[row, r];

c = a * b;

sum = sum+c;

}

ma3[row, col] = sum;

sum = 0;

}

}

mat.M11 = ma3[0, 0];

mat.M12 = ma3[0, 1];

mat.M13 = ma3[0, 2];

mat.M14 = ma3[0, 3];

mat.M21 = ma3[1, 0];

mat.M22 = ma3[1, 1];

mat.M23 = ma3[1, 2];

mat.M24 = ma3[1, 3];

mat.M31 = ma3[2, 0];

mat.M32 = ma3[2, 1];

mat.M33 = ma3[2, 2];

mat.M34 = ma3[2, 3];

mat.M41 = ma3[3, 0];

mat.M42 = ma3[3, 1];

mat.M43 = ma3[3, 2];

mat.M44 = ma3[3, 3];

return mat;

}

private static Matrix FillMat(Matrix m1, float[,] ma1)

{

ma1[0, 0] = m1.M11;

ma1[0, 1] = m1.M12;

ma1[0, 2] = m1.M13;

ma1[0, 3] = m1.M14;

ma1[1, 0] = m1.M21;

ma1[1, 1] = m1.M22;

ma1[1, 2] = m1.M23;

ma1[1, 3] = m1.M24;

ma1[2, 0] = m1.M31;

ma1[2, 1] = m1.M32;

ma1[2, 2] = m1.M33;

ma1[2, 3] = m1.M34;

ma1[3, 0] = m1.M41;

ma1[3, 1] = m1.M42;

ma1[3, 2] = m1.M43;

ma1[3, 3] = m1.M44;

return m1;

}





Re: XNA Framework Rotating an entity problems - (Not camera)

Wil Burton

Sounds like Gimbal lock. Using quaternions can eliminate this problem, I'm no expert but this might help:

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1013794&SiteID=1





Re: XNA Framework Rotating an entity problems - (Not camera)

Peter D.

Yep as you get close to zero you are gimbling your rotation matrix. I'm suprised this works in GL





Re: XNA Framework Rotating an entity problems - (Not camera)

DarthCoder

The wierd thing is, even when i use quaternions, the result is identical.

i.e,

public void Rotate(Vector3 Rotation)

{

Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.ToRadians(Rotation.X));

Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), MathHelper.ToRadians(Rotation.Y));

LocalRotation = Matrix.CreateFromQuaternion(q2 * q1);

}

 

So given that even with quats, which are supposedly gimblelock free(so i've read, not used 'em much myself) i get the same problem. model locking at certain angles, wobbling and generally not adhering to the way you'd expect the above code to act, wouldn't that suggest the problem is elsewhere in my code Did you take a look at my shader I'm not even sure if it's right, i just guessed based on my work with fixed function pipelines.

If i upload (the very small atm, only 2 days work) project, could someone take a look please  I'm officially out of ideas.

 





Re: XNA Framework Rotating an entity problems - (Not camera)

Arek Bal

I'm gonna check your problem and maybe edit this post. But for now: If you think that's your shaders and don't do anything special with your shaders....why not use BasicEffect class(I'm doing all experiments on everything with it...)instead.




Re: XNA Framework Rotating an entity problems - (Not camera)

DarthCoder

Haven't used basiceffect before, so wasn't aware it could replace the need with custom shaders. Will try it to see if it works at least. Problem with that though, is my engine is being designed to be a general purpose 3d engine. so ideally i need to be able to use custom shaders without mucking up rotations.

If you do spot a problem please do let me know, i'll buy you a pint ;)





Re: XNA Framework Rotating an entity problems - (Not camera)

DarthCoder

Here's the source code http://www.kamikazekrow.com/aw/source.zip it's only 150k and is one solution split into two projects - demo program - engine class lib (Literally one source file for the engine). So if anyone here could take minutes to check for me, i'd be extremely grateful.(You don't want to know how grateful.*wink*)

The Rotate Function is in the Entity Class. The rendering is done in the Surface Class. The shader set up is in the shader class, method setupparameters.

 

If you run, just move the mouse to rotate the box, lmb = move forward, rmb = move back.

 

Feel free to use the code however you wish anyone, if it's useful for you.

 





Re: XNA Framework Rotating an entity problems - (Not camera)

Leaf.

I've only had a quick look but I think you might be transforming by your object's world matrix twice. Your effect has LocalMatrix and WorldViewProject matrices. You set LocalMatrix to object's world matrix and then set WorldViewProject to object's world * view * projection. Then in your vertex shader you transform the vertices by LocalMatrix and then by WorldViewProject. This means your transform is something like world * world * view * project which don't look right to me...

Might be worth checking anyway.

Cheers,
Leaf.






Re: XNA Framework Rotating an entity problems - (Not camera)

Jon Watte

The matrix you calculate in the first post is multiplied in the wrong order. DirectX, and XNA, use row vectors on the left, and thus the order you want is:

Twist around front (-Z)
Pitch around right (+X)
Turn around up (+Y)
Translate by the object position

You express that as:

Matrix entityMatrix =
Matrix.CreateFromAxisAngle(-Vector3.Z, roll)
* Matrix.CreateFromAxisAngle(Vector3.X, pitch)
* Matrix.CreateFromAxisAngle(Vector3.Y, yaw)
* Matrix.CreateTranslation(position);

Btw, when this is your camera, you then would invert this matrix to create the View matrix. But you probably already knew that.






Re: XNA Framework Rotating an entity problems - (Not camera)

DarthCoder

I love you leaf. That fixed it 100%. I can not believe i missed that. Oh well, on with the engine!

Big thanks to everyone else who helped too. Especially last post, had no idea you had to invert z.