# Tank Turret rotation

This topic is 2127 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Im having trouble rotating my tanks turret on the turrets axis it orbits around the tanks centre only when I add my rotation.

this is what I'm doing I first update my meshes animation and bone matrices this is done in object space, then before

rendering.

The matrix for the base frame(bone)Turret is decomposed into its scalar, rotational, and translational components.

so I can get its rotation and add my new rotation to it, but when the new rotation is combined  it rotates about the centre

of the vehicle(the turrets are off set not at centre and they have bones at the base and offset);

If I don't add the rotation the turrets are in there correct location.

the frames Im using for the turrets all check out there axis is centre of the turret and is offset correct.

if the turrets bone is at the centre of the turret after all animation and frame updatematrices can't I just rotate on that axis ???.

//here is the code Im using

D3DXVECTOR3 OutScale;
D3DXQUATERNION OutRotation;
const D3DXQUATERNION *pq = &OutRotation;
D3DXVECTOR3 OutTranslation;
D3DXMATRIX r, s, t;
HRESULT hr = E_FAIL;
D3DXMATRIX inverst;
FLOAT d = 0.0;
D3DXMATRIX mSpin;

//ok we can rotate our turret over time
for(UINT ctr =0; ctr < mInitInfo->NumberTurretsUsed; ctr++)
{
//we want to rotate the bases y

D3DXMatrixRotationY( &mSpin, -gametime);

//we need to decompose the origanl matrix to get its trans, scale, and rotation to remate it with our new rotation
hr = D3DXMatrixDecompose(&OutScale,
&OutRotation,
&OutTranslation,
&mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]);
if(FAILED(hr))
return;//error

D3DXMatrixRotationQuaternion(&r,
pq);
D3DXMatrixMultiply(&r, &r, &mSpin);

//build a rotation matrix from its axis
//D3DXMatrixRotationAxis(&r, &OutTranslation, -gametime);

//now rebuild the matrix
D3DXMatrixTranslation(&t,  OutTranslation.x,// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._41,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._41,
OutTranslation.y,// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._42,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._42,
OutTranslation.z);//mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._43);//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._43);

D3DXMatrixScaling(&s, OutScale.x, OutScale.y, OutScale.z);

//D3DXMatrixInverse(&inverst, &d, &mInitInfo->DX10MeshBody->m_RootMesh->pMatrixOffset[TurretBaseMatrixIndex[ctr]]);

FrameTurretBaseMatrix[ctr] =  s * r * (t );//* inverst);// * mInitInfo->DX10MeshBody->m_RootMesh->pMatrixOffset[TurretBaseMatrixIndex[ctr]]);

////////////////////////////Rotate the elevation
D3DXMatrixRotationY(&mSpin, gametime);

//we need to decompose the origanl matrix to get its trans, scale, and rotation to remate it with our new rotation
hr = D3DXMatrixDecompose(&OutScale,
&OutRotation,
&OutTranslation,
&mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretElevationMatrixIndex[ctr]]);//DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]);
if(FAILED(hr))
return;//error

D3DXMatrixRotationQuaternion(&r,
pq);

//build a rotation matrix from its axis
//D3DXMatrixRotationAxis(&r, &OutTranslation, gametime);
D3DXMatrixMultiply(&r, &r, &mSpin);

//now rebuild the matrix
D3DXMatrixTranslation(&t,OutTranslation.x,// mInitInfo->DX10FrameTurretElevation[ctr]->matOriginal._41,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretElevationMatrixIndex[ctr]]._41,
OutTranslation.y,// mInitInfo->DX10FrameTurretElevation[ctr]->matOriginal._42,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretElevationMatrixIndex[ctr]]._42,
OutTranslation.z);// mInitInfo->DX10FrameTurretElevation[ctr]->matOriginal._43);//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretElevationMatrixIndex[ctr]]._43);//OutTranslation.x, OutTranslation.y, OutTranslation.z);

//D3DXMatrixInverse(&inverst, &d, &mInitInfo->DX10MeshBody->m_RootMesh->pMatrixOffset[TurretElevationMatrixIndex[ctr]]);

D3DXMatrixScaling(&s, OutScale.x, OutScale.y, OutScale.z);

FrameTurretElevationMatrix[ctr] =  s * r * (t );//* inverst);// *  mInitInfo->DX10MeshBody->m_RootMesh->pMatrixOffset[TurretElevationMatrixIndex[ctr]]);

}//end all turrets


Edited by ankhd

##### Share on other sites

It you think in terms of matrix multiplication, you'll see that there is only 1 point that ever is mapped to itself regardless of what rotation matrix you use. This point is (0,0,0) (in 3D space). Because the points that lie on the axis of rotation are mapped onto themselves, this means that an axis of rotation ever passes through (0,0,0).

So, if you want to virtually rotate around an arbitrary axis, then shift the axis first so that it passes through (0,0,0), i.e. make a translation by (-x,-y,-z) to make the initial center at (x,y,z) now be located at (0,0,0), then do the rotation as usual, then shift back by (x,y,z) to the initial position.

##### Share on other sites

I have something wrong going on here.

Ive tryed every thing to calculate the offset to apply my rotation to the bone. Ive even got the root bone and used that as the off set and nothing works the turrets

base bone always rotates about some other centre, may be its my thinking of how the bone works.

this is how the bone is rootbone(main Tank Body) -> turretleftbasebone->turretleftelevationbone->barrelleftbone.

im rotating turretleftbasebone.

I tryed these offset

turretbasebone - rootbone = same rotation

turretbasebone - turretelevationbone = same

Ive swoped the code with Quaternion. I even used the D3DXQuaternionRotationAxis to get the angle and add a bit to that the same orbit.

Heres the moded code what am I doing wrong Im Just grasping at staws now.

Edited by ankhd

##### Share on other sites

Oh that was fun.

I almost have it but its a bit off for some reason. the off set for the centre is correct. and the reposition offset should also be the same it may

come from the mSpin rotation I added but with out the spin it was a lot more off then it is now.

Ill check the model because I place the base bone off centre to the turret a bit(my rigging needs work)

heres my new bit of code it could be wrong thats why it does not line up.

//ok we can rotate our turret over time
for(UINT ctr =0; ctr < mInitInfo->NumberTurretsUsed; ctr++)
{
//we want to rotate the bases y
currentbonematicesptr = &mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]];
D3DXMatrixIdentity(&r);
D3DXMatrixIdentity(&s);
D3DXMatrixIdentity(&t);
D3DXMatrixIdentity(&temp);
D3DXMatrixIdentity(&mSpin);

//we need to decompose the origanl matrix to get its trans, scale, and rotation to remake it with our new rotation
hr = D3DXMatrixDecompose(&OutScale,
&OutRotation,
&firsttransform,
currentbonematicesptr);
if(FAILED(hr))
return;//error

//the off set is the bones combined this takes us to the vehicles centre in object space
offset.x = -(mInitInfo->DX10FrameTurretBase[ctr]->matCombined._41);//+ RootFrame->matCombined._41 );
offset.y = (mInitInfo->DX10FrameTurretBase[ctr]->matCombined._42);
offset.z = -(mInitInfo->DX10FrameTurretBase[ctr]->matCombined._43);//+ RootFrame->matCombined._43 );

//build offset transform the off set it the base bone - the elevation bone
D3DXMatrixTranslation(&t, offset.x,// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._41,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._41,
((offset.y )),// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._42,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._42,
offset.z);//

D3DXMatrixRotationQuaternion(&r,
pq);

D3DXMatrixScaling(&s, OutScale.x, OutScale.y, OutScale.z);

//the offset matrix
temp *= s;
temp *= r;
temp *= t;

//now decompose the new offset transform
hr = D3DXMatrixDecompose(&OutScale,
&OutRotation,
&OutTranslation,
&temp);
if(FAILED(hr))
return;//error

D3DXVECTOR3 Axis;
FLOAT Angle;
//get the angle and the axis
D3DXQuaternionToAxisAngle(pq,
&Axis,
&Angle);

D3DXQuaternionRotationAxis(&OutRotation,
&Axis,
-gametime);

D3DXMatrixRotationQuaternion(&r,
pq);

//using this to to the transforming
D3DXMatrixTransformation(&temp,
&OutTranslation,//CONST D3DXVECTOR3 *pScalingCenter,
NULL,//CONST D3DXQUATERNION *pScalingRotation,
&OutScale,//CONST D3DXVECTOR3 *pScaling,
&OutTranslation,//CONST D3DXVECTOR3 *pRotationCenter,
pq,//CONST D3DXQUATERNION *pRotation,
&firsttransform);//CONST D3DXVECTOR3 *pTranslation

//this is a rotation this fixes the out a bit I think ????????????????
//add this to the final matrix
D3DXQuaternionRotationAxis(&OutRotation,
&Axis,
Angle);

D3DXMatrixRotationQuaternion(&mSpin,
pq);

FrameTurretBaseMatrix[ctr] = temp * mSpin;//s * r * t;//* inverst);// * mInitInfo->DX10MeshBody->m_RootMesh->pMatrixOffset[TurretBaseMatrixIndex[ctr]]);



##### Share on other sites

Hi all.

I'm Really having trouble aligning the turrets this bit of code is the clossest I've got to perfect alinement.

But I just hacked it to gether and I think I just made it work.

Is there somthing wrong with the math I'm doing.

Thanks.....

//this is the current turret bone after the animation and the hierarachy is updated
//this array would go to the shader for skinning next for world view projection to be added
currentbonematicesptr = &mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]];
D3DXMatrixIdentity(&r);
D3DXMatrixIdentity(&s);
D3DXMatrixIdentity(&t);
D3DXMatrixIdentity(&temp);
D3DXMatrixIdentity(&mSpin);

//we need to decompose the origanl matrix to get its trans, scale, and rotation to remake it with our new rotation
hr = D3DXMatrixDecompose(&OutScale,
&firstRotation,
&firsttransform,
currentbonematicesptr);
if(FAILED(hr))
return;//error

//the off set is the bones combined this takes us to the vehicles centre in object space
float xamt = mInitInfo->DX10FrameTurretBase[ctr]->matCombined._41 + mInitInfo->DX10FrameTurretBase[ctr]->TransformationMatrix._41;
float zamt =mInitInfo->DX10FrameTurretBase[ctr]->matCombined._43 + mInitInfo->DX10FrameTurretBase[ctr]->TransformationMatrix._43;
offset.x = -(mInitInfo->DX10FrameTurretBase[ctr]->matCombined._41);//fabs(mInitInfo->DX10FrameTurretBase[ctr]->matCombined._41 - RootFrame->matCombined._41 ));
offset.y = (mInitInfo->DX10FrameTurretBase[ctr]->matCombined._42);
offset.z = -(mInitInfo->DX10FrameTurretBase[ctr]->matCombined._43 );//fabs(mInitInfo->DX10FrameTurretBase[ctr]->matCombined._43 - RootFrame->matCombined._43 ));

D3DXMatrixRotationQuaternion(&r,
pqfirst);

D3DXMatrixScaling(&s, OutScale.x, OutScale.y, OutScale.z);

D3DXMatrixIdentity(&temp);
D3DXMatrixRotationQuaternion(&r,
pqfirst);

//temp *= r;
//

//D3DXMatrixScaling(&s, 1.0, 1.0, 1.0);

//s = Scale;
//offset to rotation centre
D3DXMatrixIdentity(&t);
D3DXMatrixTranslation(&t, offset.x,// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._41,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._41,
((currentbonematicesptr->_42 )),// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._42,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._42,
offset.z);//

//rotate with time
D3DXMatrixRotationY(&mSpin, -gametime);
//temp *= s;

//det the matrix to the current turret base bone
temp = *currentbonematicesptr;
temp *= t;

//
temp *= mSpin;

//off set us back to bonespace
D3DXMatrixIdentity(&t);
D3DXMatrixTranslation(&t, -offset.x,// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._41,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._41,
((currentbonematicesptr->_42 )),// mInitInfo->DX10FrameTurretBase[ctr]->matOriginal._42,//mInitInfo->DX10MeshBody->m_RootMesh->pBoneMatrices[TurretBaseMatrixIndex[ctr]]._42,
-offset.z);//

temp *= t;

//temp *= s;

//add the original transform
temp *= *currentbonematicesptr;

//this extra r trans dont know why I need it  currentbonematicesptr should have it
temp *= r;

FrameTurretBaseMatrix[ctr] = temp;//s * r * t;//* inverst);// * mInitInfo->DX10MeshBody->m_RootMesh->pMatrixOffset[TurretBaseMatrixIndex[ctr]]);



##### Share on other sites

I must admit to not really understand what you're doing. If I had to implement the tank myself, then I would place the both turrets as child objects to the tank object. That would mean that each turret would have its own position and its own orientation relative to the tank's frame. Furthermore, I usually implement placements so that position and orientation are separately useable. With such a set-up, rotating the turrets is as simple as can be.

What exactly does the matrix currentbonematice represent, and in which co-ordinate system is this?

• 12
• 9
• 17
• 13
• 11
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!