Sphere rotation
So, I want to make a Sphere rotate, but I'm not even close to a good result... .[https://www.youtube.com/watch?v=NXVRTaU6BOI][https://www.youtube.com/watch?v=NXVRTaU6BOI] (If you don't see nothing weird about that Sphere's rotation, please watch at Speed 0.25) So, I have a variable RotX - Rotation on X - axis, RotZ - Rotation on Z - axis and World, which is the Sphere's world matrix In that video I tried something like this m_World = XMMatrixRotationX(m_fRotZ) * XMMatrixRotationZ(m_fRotX); with m_World = XMMatrixRotationRollPitchYaw(m_fRotX, 0.0f, m_fRotZ); I get the same result. Also, I have tried something like m_World = XMMatrixRotationAxis(Direction, Rotation); which looks like it works fine, but when a collision is detected and the direction is changed the rotation looks weird. Ok, that didn't work, I went mad and tried everything possible, such as m_World = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f), m_fRotZ)); m_World *= XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f), m_fRotX)); or SumofMatrices(XMMatrixRotationX(m_fRotZ), XMMatrixRotationZ(m_fRotX)); // pseudo-ish or (at this point I was completely mad) m_World = XMMatrixRotationX(m_fRotZ) * XMMatrixTransponse(XMMatrixRotationZ(m_fRotX)); and I gave up with this m_World = XMMatrixRotationY(fPi / 4) * XMMatrixRotationX(RotZ); // only for testing I think that the problem with first "solution" is that after first rotation, the x, y, z axis are not the same as in the beginning(default x, y, z axis)
your last statement pretty much sums up what i think your problem is. so for example, your last piece of code first rotates the model on the y axis, THEN it rotates it on the x axis. I guess i'm not totally sure what you want or are expecting still though. so how are you rotating the cube? if you press up it rotates on the x axis, and if you press left it rotates on the y axis for example?
on Oct 30 `16
iedoc
I tried something like [m_World *= XMMatrixRotationY( fPi / 4 ); m_World *= XMMatrixRotationX( Rotation);] (I used [ and ] for code) and here's the result https://www.youtube.com/watch?v=PMoWYbAIomw and here's the result I get with something like [m_World = XMMatrixRotationAxis(Direction, Rotation);] https://www.youtube.com/watch?v=0Tt_vHnD5SY
on Oct 31 `16
Kavarna
it looks right to me, are you still having a problem?
on Oct 31 `16
iedoc
Yes ... In the first video (m_World *= XMMatrixRotationY( fPi / 4 ); m_World *= XMMatrixRotationX( Rotation)) the ball still rotates in front (around default X - axis) and doesn't look good and in the second video (m_World = XMMatrixRotationAxis(Direction, Rotation);) when the ball "bounces off" the wall, the ball rotates around Y axis and I don't want it. It rotates like this: http://imgur.com/JHSGPtJ and I want it to be like this: http://imgur.com/mkzTLdz
on Oct 31 `16
Kavarna
is the problem when in the second video it like flips really quick when it hits the wall?
on Oct 31 `16
iedoc
Yes, that's what I want to fix
on Nov 01 `16
Kavarna
ok, i wonder if it's because your reversing the axis when it hits the wall instead of reversing the rotation speed?
on Nov 01 `16
iedoc
ah i bet i know why it's jumping with the second video. Was just looking at it an realized your probably getting the opposite orthogonal vector from the direction the ball is moving than what your looking for, which also means you probably have to reverse the rotation as well then
on Nov 01 `16
iedoc
Sign in to comment
Chosen Answer
You can get the rotation axis by crossing your direction vector with your worlds "up" vector. To make things a little easier, you can store your rotation matrix and just add the new frames rotation to that matrix. So all in all, something like this: XMVECTOR RotationAxis = XMVector3Cross( XMVectorSet( 0.0f, 1.0f, 0.0f, 1.0f ), m_Direction ); float Speed = XMVectorGetX( XMVector3Length( m_Direction ) ); rotmat *= XMMatrixRotationAxis( RotationAxis, Speed * FrameTime); m_World *= (rotmat * XMMatrixTranslationFromVector( m_Position )); Since your using a ball, the rotation is going to be a little easier to get right (speed wise). Instead of basing the speed of the rotation off the direction vector, it would actually be better to take into account the distance from the center of the sphere to the ground, and how far the ball traveled that frame. If the ball made one complete rotation that frame, meaning the rotation was 2pi, the ball will have traveled the circumference of the ball. We know that the circumference of a circle is 2pi*r, so if the radius of your ball (distance from center to edge) is 1.0 unit, the distance your ball will travel in one rotation is 2.0 * 3.14 * 1.0. now that we know all of that, we can get the angle that the ball must rotate based on the distance it has traveled. to get the final rotation for a frame (rather than speed * frametime), you will do this: float angle = (distance / circumference) * 2pi; assuming your ball moved (length of distance vector) * frametime, your final code might look like this: XMVECTOR RotationAxis = XMVector3Cross( XMVectorSet( 0.0f, 1.0f, 0.0f, 1.0f ), m_Direction ); float distance = XMVectorGetX( XMVector3Length( m_Direction ) ) * FrameTime; float ballcircumference = 2PI * ballradius; float angle = (distance / ballcircumference) * 2PI; rotmat *= XMMatrixRotationAxis( RotationAxis, angle ); m_World *= (rotmat * XMMatrixTranslationFromVector( m_Position ));