Sign in to follow this  

Aligning a 3d-object to a vector...

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi ! I have missiles flying, they have a velocity vector. What i want to get hold of is the matrix that aligns the missile-object to its velocity-vector. Since i only have the velocity-vector to begin with, i would like to use that somehow. I've tried several ways, but none work like it should, and the D3DXMatrix-functions all want angles. Anyone know a good way to do it ? (Im using directx, c++)

Share this post


Link to post
Share on other sites
Yep, just do something like this


D3DXVector3 pos(1,2,3);
D3DXVector3 vel(0,5,5);

void Entity::OnTick(float deltaTime)
{
pos += vel * deltaTime;

D3DXMatrix tm;
tm._41 = pos.x;
tm._42 = pos.y;
tm._43 = pos.z;
device->SetTransform(WORLD, &tm);
}




Drunken Hyena has some great dx9 tutorials. He covers this subject very well on his site.

Share this post


Link to post
Share on other sites
Not thats not what im asking for ;)
Updating the position, and the physics model for the missile/projectiles work as they should. Its aligning the model to the trajectory (the velocity vector) I.e rotating the model of the missile to follow the trajectory.

Thanks :)

Share this post


Link to post
Share on other sites
How about use the velocity as the missles forward vector, and caculate the "right" vector with a cross product of the forward and world up, and then calculate the "up" vector by crossing forward with right.

Share this post


Link to post
Share on other sites
Basically what DrEvil said, just use 3 unit vectors in missile coordinates for aligning to the velocity vector. Initialize the missile's vectors to the starting orientation of the missile, then just transform the forward vector to the normalized velocity vector every movement, and recalculate the right and up vectors relative to that.

Share this post


Link to post
Share on other sites
I think what you're really looking for here is a rotation matrix, right? I tend to think in terms of trigonometry instead of matrices, so I would do this:


RotateMissile(D3DXVector3 velocity)
{
D3DXMatrix=rotz;
D3DXMatrix=roty;
D3DXMatrix=xform;

D3DXMatrixRotationZ(&rotz,atan2(velocity.y,velocity.x)); //Calculate rotation around Z
D3DXMatrixRotationY(&roty,atan2(velocity.z,sqrt(velocity.x*velocity.y)));
//Then up around Y, get rid of the sqrt if you want.
D3DXMatrixMultiply(&xform,&rotz,&roty); //Then put them together and you got it.
device->SetTransform(WORLD, &xform);
}



Add any other transforms you need, like translation for position, or scaling, or whatever. Off hand I'd say you can remove the sqrt and square velocity.z, but I didn't write that because I'm afraid I'm missing something here. Also, I might have multiplied them backwards, but you get the idea. Let me know if you don't and I'll see if I can draw some triangles to explain it for you. [wink]

Hopfully someone will come along and mention the matrix-related shortcut to do this same thing, as I never bothered to learn it myself.

Share this post


Link to post
Share on other sites
Thanks, all of you.
I did it with matrices finally...
I think i will try your way to Tubular, might be faster, don't know :)


void CStaticObject::Render(const D3DXVECTOR3& _pos, const D3DXVECTOR3& _dir)
{
D3DXMATRIX worldTrans;
worldTrans._11 = _dir.x;
worldTrans._12 = _dir.y;
worldTrans._13 = _dir.z;

D3DXVECTOR3 vUp(0.0f,0.0f,-1.0f);
D3DXVECTOR3 vRight;

D3DXVec3Cross(&vRight,&vUp,&_dir);
D3DXVec3Normalize(&vRight,&vRight);

D3DXVec3Cross(&vUp,&vRight,&_dir);
D3DXVec3Normalize(&vUp,&vUp);

worldTrans._21 = vRight.x;
worldTrans._22 = vRight.y;
worldTrans._23 = vRight.z;

worldTrans._31 = vUp.x;
worldTrans._32 = vUp.y;
worldTrans._33 = vUp.z;

worldTrans._41 = _pos.x;
worldTrans._42 = _pos.y;
worldTrans._43 = _pos.z;

worldTrans._14 = 0.0f;
worldTrans._24 = 0.0f;
worldTrans._34 = 0.0f;
worldTrans._44 = 1.0f;

for(int i=0; i < m_nNumMeshes; i++)
{
if(m_pRenderBlock[i]->m_nNumOfVertices > 0)
{
((CSingleMatrixRenderBlock*)m_pRenderBlock[i])->SetTransform(worldTrans);
CDxEngine::GetInstance()->PushToPipeLine(m_pRenderBlock[i]);

}
}
}



So it finally works =)

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this