Jump to content
  • Advertisement
Sign in to follow this  
TechnoCore

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

This topic is 5054 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
Advertisement
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->m_nNumOfVertices > 0)
{
((CSingleMatrixRenderBlock*)m_pRenderBlock)->SetTransform(worldTrans);
CDxEngine::GetInstance()->PushToPipeLine(m_pRenderBlock);

}
}
}



So it finally works =)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!