Sign in to follow this  
JimmyDeemo

ID3DXSprite::SetTransform and Mouse Pos

Recommended Posts

JimmyDeemo    156
I am doing a top down shooter style game in which the player controls a character and shoot with their mouse. I currently have the player sprite rotating to look at the mouse cursor, but i'm having a problem regarding the coordinate system of the mouse and that of the sprite. I'm using ID3DXSprite::SetTransform() to position the player sprite and the following code to get the mouse position;
void CInputHandler::UpdateMouseInfo(HWND hWnd, int screenWidth, int screenHeight)
{
	//Get the current position
	GetCursorPos(&m_mousePos);
	ScreenToClient( hWnd, &m_mousePos );

	//Center
	POINT center;
	center.x = screenWidth/2;
	center.y = screenHeight/2;

	m_mousePosFromCenter.x = m_mousePos.x - screenWidth/2;
	m_mousePosFromCenter.y = m_mousePos.y - screenHeight/2;
}
Currently as the coorinate systems don't match up, the position the sprite rotates around is not quite the cursor. So i know what happening but i'm not sure what to do to rectify it. Should i be converting the mouse position into the sprites system or should i be drawing the sprite using pixels as positions. I did/have posted this in the for beginners but thought it might get an answer here. I think that i'm getting confused as to how i'm actually drawing stuff.

Share this post


Link to post
Share on other sites
JimmyDeemo    156
Hi Steve, yes i have done that.

I think i'm having trouble becuase the sprite is positioned in 3D. I'm just not sure whats the best way to rectify it. Would it be helpfull if i posted a little demo exe to illustrate what i'm decribing above?

Share this post


Link to post
Share on other sites
JimmyDeemo    156
Anybody have any other ideas for me? I'm thinking that i should use a picking like system to project a ray down the z axis and then work out the point at which the ray crosses the xy plane. I think that might work.

Share this post


Link to post
Share on other sites
JimmyDeemo    156
I would really appreciate any idea on this. Anything that i might have missed or i'm not doing properly. Any requests for more information so they can help easier.

I have now implemented a system to convert the mouse position into 3D coordinates. But its actually made the problem worst and now the sprite seems to be being drawn at a scaled up version of the mouse position. I can make a little vid it it would illustrate it better.

I think the question i need to ask it, if you wanted to draw a 3D object on the xy plane that was drawn direction underneath the mouse cursor, how would you do it?

Here is my code for calculating the mouse position. Seems to give me ok results (bar the scaling).

//-----------------------------------------------------------------------------
// Name : CFarmer::Update
// Desc : Updates the farmer.
// Param : const CInputHandler *pInput - Const pointer to the Input Handler
// Param : float delta - The time step for this frame
//-----------------------------------------------------------------------------
void CFarmer::Update( float delta, float screenW, float screenH, const CInputHandler* const pInput, const CCamera* const pCamera )
{
//Player input
//TODO: Make keys customizable
if( pInput->KeyIsDown( 'W' ) )
{
m_pos.y -= m_SpeedIncrease * delta;
}

if( pInput->KeyIsDown( 'S' ) )
{
m_pos.y += m_SpeedIncrease * delta;
}

if( pInput->KeyIsDown( 'A' ) )
{
m_pos.x -= m_SpeedIncrease * delta;
}

if( pInput->KeyIsDown( 'D' ) )
{
m_pos.x += m_SpeedIncrease * delta;
}


//Calculation for rotation.
D3DXVECTOR2 mousePos( static_cast<float>(pInput->MousePos().x), static_cast<float>(pInput->MousePos().y) );

//Mouse pos needs to be projected as a ray into 3D space as thats what the farmers position is.
//First get the proj matrix.
D3DXMATRIX proj = pCamera->Proj();

//Calculate the direction of the ray in view space
D3DXVECTOR3 dir( ((2.0f*mousePos.x/screenW - 1.0f) / proj(0,0)), ((-2.0f*mousePos.y/screenH + 1.0f) / proj(1,1)), 1.0f );
D3DXVECTOR3 origin( 0.0f, 0.0f, 0.0f );

//The ray now needs to be converted to world space, use the inverse of the view matrix
D3DXMATRIX invView;
D3DXMatrixInverse( &invView, 0, &pCamera->View() );

//Now transform it to world space.
D3DXVECTOR3 rayDir, rayOrigin;
D3DXVec3TransformCoord( &rayOrigin, &origin, &invView );
D3DXVec3TransformNormal( &rayDir, &dir, &invView );
D3DXVec3Normalize( &rayDir, &rayDir );

//Define the plane to intersect, i.e. the xy plane facing the player.
D3DXVECTOR3 planeNormal( 0.0f, 0.0f, -1.0f );
D3DXVECTOR3 pointOnPlane( 0.0f, 0.0f, 0.0f );

//Find the point on the ray that intersects with the plane
//We can use the equation N.(q-x) / N.D.

float numerator = D3DXVec3Dot( &planeNormal, &(pointOnPlane - rayOrigin) );
float denominator = D3DXVec3Dot( &planeNormal, &rayDir );
float t = numerator / denominator;

//Now plug t into the ray equation to get the position.
D3DXVECTOR3 mousePosW = rayOrigin + (t*rayDir);

m_pos = 0.5*mousePosW;

//Components
float xComp = mousePosW.x - m_pos.x;
float yComp = mousePosW.y - m_pos.y;

m_rotation = atan2( yComp, xComp );
}

//-----------------------------------------------------------------------------
// Name : CFarmer::TransMatrix
// Desc : Returns a matrix representing the Farmers position and rotation.
//-----------------------------------------------------------------------------
D3DXMATRIX CFarmer::TransMatrix() const
{
D3DXMATRIX T, R;
D3DXMatrixTranslation( &T, m_pos.x, m_pos.y, m_pos.z );
D3DXMatrixRotationZ( &R, m_rotation+D3DXToRadian(90.0f) );

return (R * T);
}


Don't ask why i have a farmer class. :D

Share this post


Link to post
Share on other sites

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