Jump to content
  • Advertisement
Sign in to follow this  
Anddos

Moving head bone with mouse, need to create a view matrix

This topic is 2207 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

I am controlling the skinned meshs head with the mouse, what I want todo next is press a key and switch to the view the head is looking at and build the look,up,right vectors to work with D3DXMatrixLookAtLH

The below code is not mine,its from Character Animation with Direct3D which is a great book , I just want to make a mod so when I move the head with mouse I am controlling what he is looking at smile.png

 

Here is a video for demonstration purposes

 

[youtube]http:

[/youtube]

 

My guess would be I need to covert this matrix , rotation * m_pHeadBone->CombinedTransformationMatrix; to the 3 vector paramaters for the Lookat function,thanks for reading..

#include "InverseKinematics.h"
#include "skinnedMesh.h"
// Setup forward vectors and get bone pointers for our example
InverseKinematics::InverseKinematics(SkinnedMesh* pSkinnedMesh)
{
 m_pSkinnedMesh = pSkinnedMesh;
 // Find the head bone
 m_pHeadBone = (Bone*)m_pSkinnedMesh->GetBone("Head");
 // Exit if there is no head bone
 if(m_pHeadBone != NULL)
 {
  // Calculate the local forward vector for the head bone
  // Remove translation
  D3DXMATRIX headMatrix = m_pHeadBone->CombinedTransformationMatrix;
  headMatrix._41 = 0.0f;
  headMatrix._42 = 0.0f;
  headMatrix._43 = 0.0f;
  headMatrix._44 = 1.0f;
  D3DXMATRIX toHeadSpace;
  if(D3DXMatrixInverse(&toHeadSpace, NULL, &headMatrix) == NULL)
   return;
  // Our model is looking towards -z in the content
  D3DXVECTOR4 vec;
  D3DXVec3Transform(&vec, &D3DXVECTOR3(0, 0, -1), &toHeadSpace);
  m_headForward = D3DXVECTOR3(vec.x, vec.y, vec.z);
 }
}
// Head IK test function
void InverseKinematics::UpdateHeadIK()
{
 // Exit if there is no head bone
 if(m_pHeadBone == NULL)
  return;
 //Get look at point from cursor location
 POINT p;
 GetCursorPos(&p);
 p.x = max(min(p.x, 800), 0);
 p.y = max(min(p.y, 600), 0);
 float x = (p.x - 400) / 800.0f;
 float y = (p.y - 300) / 600.0f; 
 D3DXVECTOR3 lookAt(x, 1.5f - y, -1.0f);
 // Restrict head movement to 60 degrees
 ApplyLookAtIK(lookAt, D3DXToRadian(60.0f));
}
// Uses shortest arc rotation algorithm to turn the head bone towards a position
void InverseKinematics::ApplyLookAtIK(D3DXVECTOR3 &lookAtTarget, float maxAngle)
{
 // Start by transforming to local space
 D3DXMATRIX mtxToLocal;
 D3DXMatrixInverse(&mtxToLocal, NULL, &m_pHeadBone->CombinedTransformationMatrix);
 // Footnote: the matrix inverse could be avoided if we would ignore to update the local transform
 D3DXVECTOR3 localLookAt;
 D3DXVec3TransformCoord(&localLookAt, &lookAtTarget, &mtxToLocal );
 // Normalize local look at target
 D3DXVec3Normalize(&localLookAt, &localLookAt);
 // Get rotation angle and angle
 D3DXVECTOR3 localRotationAxis;
 D3DXVec3Cross(&localRotationAxis, &m_headForward, &localLookAt);
 D3DXVec3Normalize(&localRotationAxis, &localRotationAxis);
 float localAngle = acosf(D3DXVec3Dot(&m_headForward, &localLookAt));
 // Limit angle
 localAngle = min( localAngle, maxAngle );
 // Apply the transformation to the bone
 D3DXMATRIX rotation;
 D3DXMatrixRotationAxis(&rotation, &localRotationAxis, localAngle);
 m_pHeadBone->CombinedTransformationMatrix = rotation * m_pHeadBone->CombinedTransformationMatrix;
 // Update changes to child bones
 if(m_pHeadBone->pFrameFirstChild)
 {
  m_pSkinnedMesh->UpdateMatrices((Bone*)m_pHeadBone->pFrameFirstChild, &m_pHeadBone->CombinedTransformationMatrix);
 }
}
Edited by Anddos

Share this post


Link to post
Share on other sites
Advertisement

You can use the inverse of the m_pHeadBone matrix as a view matrix. This matrix lets you transform a scene into the local space of the head(-camera), as you effectively always do when multiplying by a view matrix.

Share this post


Link to post
Share on other sites

"Character Animation with Direct3D" is a great book as introduction, I have it.

I said introduction because it uses D3DX so he doesn't go deep of how it is done.

Inverse of a world matrix is always a view matrix, so just inverse the world matrix of the bone, the combined is what you want (local * parentWorld).

You don't need to make a "look at" matrix, you only need to inverse the combined and use it as view matrix.

Edited by Alundra

Share this post


Link to post
Share on other sites

D3DXMatrixInverse(&m,NULL,&m_pHeadBone->CombinedTransformationMatrix)

g_pDevice->SetTransform(D3DTS_VIEW, &m);

 

so it would be something like this ? , I cant think how I am going to switch the view matrix now , like enalble and disable, I know its with bools , dosent the settransform have to go in the rendering loop?

Share this post


Link to post
Share on other sites

You can use boolean to switch the view or you can store an array of view and a number who says the current view.

You have to check the input key used for the switch. When it's pressed, adds one or subtracts one.

You have to check the number limits (0 -> MaxView). "SetTransform" must be set in the rendering.

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.

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!