MARS_999 1627 Report post Posted June 17, 2009 I have a ball on a track and right now the ball moves side to side and I change the rotation based on which key the user has pressed. Problem is when the user presses fwd and left/right the ball doesn't say 45 degrees. So to make the ball look a bit more realistic in movements what am I needing to do to get this ball to rotate correctly when moving 2 directions at once vs. 1(fwd,right, left) Their isn't any backwards... //used to calculate playerDir and is a scalar //used later on with a playerTransformMatrix to determine playerPos.xyz velocityClamped = velocity; NX::MATH::Clamp<float>(velocityClamped, .5f, 1.0f); if(playerRight) playerDir += velocityClamped * PLAYERDIR_ACCEL_CONSTANT * DIR_CHANGE_RATE; if(playerLeft) playerDir -= velocityClamped * PLAYERDIR_ACCEL_CONSTANT * DIR_CHANGE_RATE; //for the rotation of the ball if(playerRight) rotMatrix.Rotate(angle * velocity, false, false, true);//z axis else if(playerLeft) rotMatrix.Rotate(-angle * velocity, false, false, true);//z axis else rotMatrix.Rotate(angle * velocity, true, false, false);//x axis rotMatrix is a 4x4 matrix thanks 0 Share this post Link to post Share on other sites
Ariste 296 Report post Posted June 17, 2009 There's not much to go off of from that code, but if I understand correctly, you're trying to have the combination key-press LEFT + UP create a 45 degree rotation as opposed to a full 90 (or 0) degree rotation. The problem with your code, then, is the if/else if/else sequence. In the event of a LEFT + UP combination, only one of those if blocks is going to be executed; namely, the first one that evaluates to true.Try changing the code to a series of simple ifs. This way, each of the statements that evaluates to true will be executed, not just the first one. 0 Share this post Link to post Share on other sites
MARS_999 1627 Report post Posted June 17, 2009 Nah that doesn't work, the ball goes all nuts like you are stretching it out and contracting it... 0 Share this post Link to post Share on other sites
Ariste 296 Report post Posted June 17, 2009 LOL. So much for listening to me [smile]Out of curiosity, what does your code look like now? 0 Share this post Link to post Share on other sites
MARS_999 1627 Report post Posted June 17, 2009 I used thisif(playerRight) rotMatrix.Rotate(angle * velocityClamped * .1f, false, false, true);if(playerLeft) rotMatrix.Rotate(-angle * velocityClamped * .1f, false, false, true);if(playerFwd) rotMatrix.Rotate(angle * velocity * .00025f, true, false, false); 0 Share this post Link to post Share on other sites
jyk 2095 Report post Posted June 18, 2009 Can you post your Rotate() function? 0 Share this post Link to post Share on other sites
MARS_999 1627 Report post Posted June 18, 2009 Hi jky,I changed my Rotate to sepearate functions but still does the same thing as before. I can only rotate one axis at a time with this rotate function. What I am wondering is do I need to do some kind of rotational velocity or angular velocity? I have no idea I am not looking for realistic simulation here, but would like the ball to spin on the correct axis when the player moves in those directions?Thanks//Rotate a 3D point in Radians not Degrees void RotateX(T angle) { T sine = sin(angle); T cosine = cos(angle); matrix[5] = cosine; matrix[6] = sine; matrix[9] = -sine; matrix[10] = cosine; } //Rotate a 3D point in Radians not Degrees void RotateY(T angle) { T sine = sin(angle); T cosine = cos(angle); matrix[0] = cosine; matrix[2] = -sine; matrix[8] = sine; matrix[10] = cosine; } //Rotate a 3D point in Radians not Degrees void RotateZ(T angle) { T sine = sin(angle); T cosine = cos(angle); matrix[0] = cosine; matrix[1] = sine; matrix[4] = -sine; matrix[5] = cosine; } 0 Share this post Link to post Share on other sites
jyk 2095 Report post Posted June 18, 2009 What are the types of velocity and playerDir?I notice that your rotation functions don't set the matrix to identity before setting the relevant elements. Is this intentional? This means that the results may be incorrect if the matrix is not already identity. 0 Share this post Link to post Share on other sites
MARS_999 1627 Report post Posted June 18, 2009 both are scalar floats and I call identity before the rotate in a separate call 0 Share this post Link to post Share on other sites
KOzymandias 132 Report post Posted June 18, 2009 Don't you need 3 rotation matrices, one for each axis, then rotMatrix would be the product of those 3 matrices (in the right order) ? Your RotateX/Y/Z functions assume the matrix is identity, so you can't call those functions successively on the same matrix. It overrides part of the last rotation, stretching the ball. 0 Share this post Link to post Share on other sites
jyk 2095 Report post Posted June 18, 2009 Does velocity represent angular velocity? What does playerDir represent? Is it an angle? Also, where does the angle variable come from? (The lack of context makes it a bit difficult to make sense of the code, IMO.)As for the 'rotate' functions, they should really set every element of the matrix to the appropriate value, rather than making assumptions about the previous state of the matrix (IMO). Also, I don't see you setting the matrix to identity anywhere in your code - are you sure it's set to identity before the rotation functions are called? Are you setting the matrix to identity and then making multiple calls to the rotation functions with the expectation that the rotations will accumulate in some way? 0 Share this post Link to post Share on other sites
MARS_999 1627 Report post Posted June 18, 2009 Quote:Original post by jykDoes velocity represent angular velocity? What does playerDir represent? Is it an angle? Also, where does the angle variable come from? (The lack of context makes it a bit difficult to make sense of the code, IMO.)As for the 'rotate' functions, they should really set every element of the matrix to the appropriate value, rather than making assumptions about the previous state of the matrix (IMO). Also, I don't see you setting the matrix to identity anywhere in your code - are you sure it's set to identity before the rotation functions are called? Are you setting the matrix to identity and then making multiple calls to the rotation functions with the expectation that the rotations will accumulate in some way?I haven't made it represent nothing, as I just wanted to ball to move and look correct never was concerned with realistic movements or simulations on the ball. So velocity is just another name for speed...Yes, I am calling Identity() and I changed the velocity to speed to clear up this isn't a vector I am using and starting to think I need a vector for my fwd movement and side to side to get this to work????//Draw Player scaleMatrix.Identity(); rotMatrix.Identity(); matrix.Identity(); glPushMatrix(); if(playerRight || playerLeft) { rotMatrix.ArbitraryRotation(NX::MATH::DegToRad(angle) * speedClamped, 1, 1, 1);// rotMatrix.RotateX(NX::MATH::DegToRad(angle) * speedClamped * .1f); } else { rotMatrix.ArbitraryRotation(NX::MATH::DegToRad(angle) * speed, 1, 1, 1);// rotMatrix.RotateX(NX::MATH::DegToRad(angle) * speed * .001f); } scaleMatrix.Scale(playerScale, playerScale, playerScale, true, true, true); playerPos = playerTransformMatrix & NX::MATH::vec3<float>(0.0f, 0.0f, playerDir); matrix.Translate(playerPos); playerSphere.UpdateCenter(matrix); matrix *=scaleMatrix; matrix *=rotMatrix; glMultMatrixf(matrix.matrix); DrawBall(); glPopMatrix(); 0 Share this post Link to post Share on other sites
KOzymandias 132 Report post Posted June 18, 2009 I can understand how to use ArbitraryRotation() with only one angle and one 'true', like it was in the first post. But I think it can't be used with 3 'true/1'. What's it gonna do, rotate around x, then y, then z by angle radian ? Why don't you just use 3 rotation matrices like this ?Matrix4 rotX, rotY, rotZ, rotYXZ;rotX.SetRotationX(angle_x);rotY.SetRotationY(angle_y);rotZ.SetRotationZ(angle_z);rotXYZ = rotX * rotY * rotZ; // or rather rotY * rotX * rotZ;Then if you want, you can code a RotateXYZ functions that takes 3 angles (and no bool, an angle of 0 is enough) and makes rotXYZ without intermediary matrices, but at least it's more clear what the resulting matrix is. Note that you probably don't need the rotY matrix since you only need to go forward and on the side. 0 Share this post Link to post Share on other sites
MARS_999 1627 Report post Posted June 18, 2009 Quote:Original post by KOzymandiasI can understand how to use ArbitraryRotation() with only one angle and one 'true', like it was in the first post. But I think it can't be used with 3 'true/1'. What's it gonna do, rotate around x, then y, then z by angle radian ? Why don't you just use 3 rotation matrices like this ?*** Source Snippet Removed ***Then if you want, you can code a RotateXYZ functions that takes 3 angles (and no bool, an angle of 0 is enough) and makes rotXYZ without intermediary matrices, but at least it's more clear what the resulting matrix is. Note that you probably don't need the rotY matrix since you only need to go forward and on the side.I will try it later, but will this solve my issue at hand with the ball rotating correctly when moving side to side and side+fwd? 0 Share this post Link to post Share on other sites