Direct3D Background Sphere Rotation

Started by
3 comments, last by sdoherty55 21 years, 10 months ago
I have a airplane where the y dimension is static and parallel to the screen, z is vertical in relation to the screen, and x is horizontial in relation to the screen. The camera is positioned stationary just above the airplane and is also parallel to the screen. Thus the airplane is basically 2D where x is left to right and z is up and down. Note that the airplane moves in the direction that it is pointing, but the camera is always repositioned just above the plane. The airplane is an enclosed by an inversly scaled sphere containing a star texture (I beleive this is similar to a sky box). When the airplan is pointing up, and rotate the sphere in the reverse direction of the movement. When the airplan is pointing right I do the same. This seems to work fine. The problem is when I rotate in two directions at the same time a strange spinning occurs? I know that there can be Gimbal Lock problems when you rotate in three directions, but I am really only rotating in two different directions? I have tried a couple different solutions, but without knowing why this is happening it seems as though I am just wasting time: 1st Solution (standard three vector rotation):
    
D3DXMatrixIdentity(&m_matWorld);

D3DXMatrixTranslation(&matWorld, m_vPosition.x, m_vPosition.y, m_vPosition.z);

D3DXMatrixRotationX( &mRotateX, -m_vRotate.x );
D3DXMatrixRotationY( &mRotateY, -m_vRotate.y );
D3DXMatrixRotationZ( &mRotateZ, -m_vRotate.z );

D3DXMatrixMultiply( &mTemp, &mRotateX, &mRotateZ );
D3DXMatrixMultiply( &m_matWorld, &mTemp, &m_matWorld ); 
  


2nd Attempt - Quaternion (wasn't convinced this was the solution) 
      
D3DXMatrixTranslation(&mTranslation, m_vPosition.x, m_vPosition.y, m_vPosition.z);
D3DXMatrixTranslation(&mTranslation, 0.0f, 0.0f, 0.0f);
D3DXMatrixMultiply (&m_matWorld, &mTranslation, &m_matWorld);

D3DXMATRIX matR;
D3DXQUATERNION qR;
D3DXQuaternionRotationYawPitchRoll (&qR, m_vRotate.x, m_vRotate.y, m_vRotate.z);	// step 2

D3DXMatrixRotationQuaternion (&matR, &qR);							// step 3

D3DXMatrixMultiply (&m_matWorld, &matR, &m_matWorld);			// step 4


//	D3DXMatrixInverse (&m_matWorld, NULL, &m_matWorld);				// step 5  (Don't Think I need)


  



3rd Attempt - code from the GameDev.ner where I should be rotating by the camera as opposed to the object.
      
Up_Vector    = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
Right_Vector = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );
Look_Vector  = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixRotationAxis(&YawMat, &Up_Vector, m_vRotate.x);  // Yaw


D3DXVec3TransformCoord(&Look_Vector, &Look_Vector, &YawMat);
D3DXVec3TransformCoord(&Right_Vector, &Right_Vector, &YawMat);
D3DXMatrixRotationAxis(&PitchMat, &Right_Vector, m_vRotate.y); // Pitch

D3DXVec3TransformCoord(&Look_Vector, &Look_Vector, &PitchMat);
D3DXVec3TransformCoord(&Up_Vector, &Up_Vector, &PitchMat);
D3DXMatrixRotationAxis(&RollMat, &Look_Vector, m_vRotate.z); // Roll

D3DXVec3TransformCoord(&Up_Vector, &Up_Vector, &RollMat);
D3DXVec3TransformCoord(&Right_Vector, &Right_Vector, &RollMat);

D3DXMatrixIdentity(&m_matWorld);
m_matWorld._11 = Right_Vector.x;
m_matWorld._12 = Up_Vector.x;
m_matWorld._13 = Look_Vector.x;
m_matWorld._21 = Right_Vector.y;
m_matWorld._22 = Up_Vector.y;
m_matWorld._23 = Look_Vector.y;
m_matWorld._31 = Right_Vector.z;
m_matWorld._32 = Up_Vector.z;
m_matWorld._33 = Look_Vector.z;
m_matWorld._41 = - ((m_vPosition.x * Right_Vector.x) + (m_vPosition.y * Right_Vector.y) + (m_vPosition.z * Right_Vector.z));
m_matWorld._42 = - ((m_vPosition.x * Up_Vector.x)    + (m_vPosition.y * Up_Vector.y)    + (m_vPosition.z * Up_Vector.z));
m_matWorld._43 = - ((m_vPosition.x * Look_Vector.x)  + (m_vPosition.y * Look_Vector.y)  + (m_vPosition.z * Look_Vector.z));
//?	m_matWorld._41 = m_vPosition.x; 

//?	m_matWorld._42 = m_vPosition.y;

//?	m_matWorld._43 = m_vPosition.z;


    
Seemed like the third option should have been correct, can someone point me in the correct direction? Thanks [edited by - sdoherty55 on June 6, 2002 1:44:16 PM]
Advertisement
Well, I think it''s a math problem, due to matrix concatenation.
Let''s see the first solution.
after you have set your matrix, you multiply Xrotation by the Z rotation. So what you get, in term of "visual effect", is first a rotation of the sphere according to one rotation, and then a second rotation, relative to the result of the first rotation.
The result is not a sphere rotated of angleX around X axis (absolute) and angleZ around Zaxis(absolute), but a composition of 2 rotations (here i think it''s first Zrotation and then Xrotation).
If you really want to keep your plane still and get a correct rotation, you will have to recalculate a X angle after having applied Zrotation (with some formula about projections involving dot and cross products).
Or more easily, you could change the définition of your x and z angle: you could think about using an angular speed, I mean using the difference between current angle and previous one or whatever, so that you rather have an angular increment, and you apply the resulting rotation matrix to the previous one (from the previous frame). (In this case, beware of translations: since you will add transformation from previous frame to the current, you need to use for the current frame a translation matrix involving the speed and not the absolute position...)
The user can provide an impulsion to set angular speed to a value (fixed or proportional to mouse movement for example).
You can also probably use quaternions but I don''t know enough about them to provide any advices.

Finally, I would suggest you simply apply rotation/translation to your plane and just center the sphere on the plane. (This will avoid the conceptual inversion of movement, when thinking about sphere movement, which can be quite confusing)

I hope it will help,
Freeman_CIT

regards,Freeman_CIT
Freeman_CIT,

Thanks for your response, I have a couple of questions:


You Said:
"If you really want to keep your plane still and get a correct rotation, you will have to recalculate a X angle after having applied Zrotation (with some formula about projections involving dot and cross products)."

Questions:
Why would I apply the zRotation prior to the xRotation? Could you elaborate further on the furmula using projections and involving the dot and cross product?

You Said:
"Or more easily, you could change the définition of your x and z angle: you could think about using an angular speed, I mean using the difference between current angle and previous one or whatever, so that you rather have an angular increment, and you apply the resulting rotation matrix to the previous one (from the previous frame). (In this case, beware of translations: since you will add transformation from previous frame to the current, you need to use for the current frame a translation matrix involving the speed and not the absolute position...)
The user can provide an impulsion to set angular speed to a value (fixed or proportional to mouse movement for example)."

Questions:
How do mesh the previous Rotation matrix with a new Rotation matrix calculated based on a angular speed? Why would this be any different than the other solution? Can you elaborate further on how I would add the transformation matrix into the final mix?

You Said:
"Finally, I would suggest you simply apply rotation/translation to your plane and just center the sphere on the plane. (This will avoid the conceptual inversion of movement, when thinking about sphere movement, which can be quite confusing)"

Questions:
What do you mean by conceptual inversion? Are you saying that I should leave the sphere stationary and rotate the camera around the around the sphere in the same direction as the airplane?

Thanks



[edited by - sdoherty55 on June 6, 2002 6:20:40 PM]
I check some point about matrix concatenation and I try to answer your question ASAP.
(I am quite busy right now, sorry)
regards,Freeman_CIT
ok, here are some more explanation, and I hope I have not misunderstood you.
1) the problem is that matrix concatenation are operating that way

Adding transformation is simply done by multiplying matrix the right way (see point 2).
Here is another article that will explain everything about 3D math and matrix concatenation better than me:
http://www.gamedev.net/reference/programming/features/d3d7im2/
Notice that the author uses pitch/yaw/roll and not absolute angles

Take a look at this sample. I haven’t intensively read it, but it seems to cover some point of your problem.
http://www.gamedev.net/reference/programming/features/qpowers/
it’s using quaternion but seems to do what you want (except that it copes with camera/player rotation, instead of environment rotation…)

To get back to your problem, i.e. using absolute angle without quaternion, you will have to apply the first rotation (for example X rotation), and a second one with a calculated angle. After that, you have your new transformed object and a new set of 3 vectors tX,tY,tZ representing current object orientation, that are the result of transformed X,Y,Z (world) axis (our object is, before transformation, aligned with the world). in fact angleX and angleZ are comparable to coordinates in a polar coordinate system. So what you need is converting those coordinates to usable rotation angles. So let''s say you want to put pX,pY,pZ (plane axis, that are initially the same as world axis) from current orientation, to a new one (result = tX,tY,tZ). You first need do clearly define angles you are using to describe your orientation: if we call aX the angle in relation to x (screen) offset, it will result in a rotation around Z, and aZ (in relation to z screen offset), will result in a rotation around X axis. But we need to see them as coordinate describing a point (representing tY, which is the direction of the plane): aX is the angle between Y axis and the projection of tY on the plane (X,Y). aZ is the angle between the projection of tY on the plane (Z,Y) and Y axis. So you see here that when you apply only one rotation with for example aX around Z, you will get correct rotation. But aZ is no more valid, since tX axis is not pointing the same way as X. Let''s call tX1,tY1,tZ1 axis resulting of a first transformation (i.e. rotation aX (previously called angleZ) around Z axis (called R1)). tZ1 is Z (no changes). tX1 and tY1 are just X and Y transformed by R1. So we know tX1 and tY1 coordinates (Cartesian). And we also know tY: indeed we have angular coordinates of this vector (aX,aZ). Then we can access Cartesian coordinates of tY. Moreover, tY and tY1 are coplanar. So the dot product (tY1,tY) will give you the angleX between tY1 and tY (assuming the length of those vectors is 1, you can normalize before dot product otherwise). And this angle is exactly the one we need, to rotate around tX1 axis. Just be careful with matrix product, it’s not commutative…
The crucial point is the conversion from polar coordinates to Cartesian (for tY) and it depends on your definition of aX and aZ. I haven''t provided any formula, since I haven''t them with me now (I am at work, and I am not working in computer science ), but you probably can get them on Gamedev in math section. For coordinates conversion, it''s a mathematical "standard" (all good math books have them).

2)Assume you have the transformation matrix from the previous frame. This matrix holds all properties of previous state (if we have 4D homogenous matrix!): position, rotation, scale...
If you multiply this matrix by another transformation (TR), you will have either previous transformed by TR, either TR transformed by previous matrix, depending on the matrix product you perform. So imagine, in our case, we are stuck to origin (no translation), the previous matrix hold previous state and we want to rotate the object from the old state/orientation by a new one. We first need to rotate our object with our new matrix, and then relocate it to the old state.
This is different from previous point of view because you don''t use aX and aZ as absolute value, but are considered as offset (the example you gave show that you consider m_vRotate members as absolutes angles), i.e. pitch/yaw. User doesn''t control directly the absolute angle, but just say "turn up with this speed" etc…

3) Yes. Turning the world around, instead of the player seems tricky. I suggest you stick the camera behind the plane, turn/move the plane and leave the world still. Quote that my explanation above are proposed for a moving player... you will have to invert the whole stuff for a rotating world...



PS: Please, excuse my English which might be a little "twisted", I am French...
regards,Freeman_CIT

This topic is closed to new replies.

Advertisement