// Controlla se colpito dal mirino
bool SottoTiro(POINT Mouse, D3DXMESHCONTAINER_EX *pMesh)
{
D3DXVECTOR3 vPickRayDir;
D3DXVECTOR3 vPickRayOrig;
//x, y and z are my camera position
GetCursorPos( &Mouse );
ScreenToClient( g_hWndMain, &Mouse );
// Transform the screen space pick ray into 3D space
vPickRayDir.x = -(float)Mouse.x;
vPickRayDir.y = -(float)Mouse.y;
vPickRayDir.z = z-10000;
vPickRayOrig.x = x;
vPickRayOrig.y = y;
vPickRayOrig.z = z;
// clear the hit flag
bool m_bHit=FALSE;
// test for intersection
DWORD dwIndex;
int Hit;
float u,w;
float dist;
D3DXIntersect(pMesh->pSkinMesh,&vPickRayOrig,&vPickRayDir,&Hit,&dwIndex,&u,&w,&dist,NULL,NULL);
if(Hit)
m_bHit=false;
else
m_bHit=true;
return m_bHit;
}
But it doesn''t work!
Who could help me to find a real solution to the problem?!
THANKS A LOT!!!
^__^
BYE,
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
D3DXIntersect()
Ok I''ve tried a lot of things but I can''t find a solution of how to use in the real and useful way this function!
I want only to check if my ray is pointing to a mesh.
My ray origin must be the camera (I suppose) and the direction is my mouse coordinates.
I''ve tried with this:
Remember that your mesh vertices are stored in model space, not world space. When you perform an intersection test, both your model and the ray have to be in the same coordinate space for it to work.
You have two choices, you can either transform all of your mesh vertices into world space (bad idea because you could end up transforming thousands of verts) or you could just transform your ray from world space into model space (good idea).
To transform your ray into model space, you need to compute the inverse of the original world transform matrix that you used to render your mesh in your 3D scene. You then take this inverse matrix and use it to transform your ray from world space to model space. In code it would look like this:
Hope this helps,
neneboricua
You have two choices, you can either transform all of your mesh vertices into world space (bad idea because you could end up transforming thousands of verts) or you could just transform your ray from world space into model space (good idea).
To transform your ray into model space, you need to compute the inverse of the original world transform matrix that you used to render your mesh in your 3D scene. You then take this inverse matrix and use it to transform your ray from world space to model space. In code it would look like this:
D3DXMATRIX matInverse;D3DXMatrixInverse(&matInverse, NULL, &matMeshWorld);D3DXVECTOR3 vModelSpaceRayPos, vModelSpaceRayDir;D3DXVec3TransformCoord(&vModelSpaceRayPos, &vPickRayOrig, &matInverse);D3DXVec3TransformNormal(&vModelSpaceRayDir, &vPickRayDir, &matInverse);// Use your new ray to intersect with your mesh...D3DXIntersect(.....)
Hope this helps,
neneboricua
Ok, I've tried as you says as you can see...
BUT IT STILL DOESN'T WORK!!!
I NEED HELP, PLEASE!!!!
^__^
THANKS A LOT!!!
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
[edited by - GENTS on June 9, 2004 2:41:43 PM]
BUT IT STILL DOESN'T WORK!!!
// Controlla se colpito dal mirino bool SottoTiro(D3DXMESHCONTAINER_EX *Mesh, CObjCollection Obj, CCamera cam){ bool m_bHit=FALSE; BOOL bHit; D3DXVECTOR3 vPickRayDir; D3DXVECTOR3 vPickRayOrig; D3DXMATRIXA16 matProj; g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &matProj ); POINT ptCursor; GetCursorPos( &ptCursor ); ScreenToClient( g_hWndMain, &ptCursor ); // Compute the vector of the pick ray in screen space D3DXVECTOR3 v; v.x = ( ( ( 2.0f * ptCursor.x ) / g_WinWidth ) - 1 ) / matProj._11; v.y = -( ( ( 2.0f * ptCursor.y ) / g_WinHeight ) - 1 ) / matProj._22; v.z = 1.0f; // Get the inverse of the composite view and world matrix D3DXMATRIXA16 matView, matWorld, m; g_pD3DDevice->GetTransform( D3DTS_VIEW, &matView ); g_pD3DDevice->GetTransform( D3DTS_WORLD, &matWorld ); m = matWorld * matView; D3DXMatrixInverse( &m, NULL, &m ); // Transform the screen space pick ray into 3D space vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31; vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32; vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33; float x, y, z; cam.GetPosition( x, y, z ); vPickRayOrig.x = x; vPickRayOrig.y = y; vPickRayOrig.z = z; LPD3DXBASEMESH pMesh = Mesh->pSkinMesh; D3DXMATRIX matInverse, LocMatrix; Obj.GetLocal( LocMatrix ); D3DXMatrixInverse(&matInverse, NULL, &LocMatrix ); D3DXVECTOR3 vModelSpaceRayOrig, vModelSpaceRayDir; D3DXVec3TransformCoord(&vModelSpaceRayOrig, &vPickRayOrig, &matInverse); D3DXVec3TransformNormal(&vModelSpaceRayDir, &vPickRayDir, &matInverse); // Collect only the closest intersection DWORD dwFace; FLOAT fBary1, fBary2, fDist; D3DXIntersect(pMesh, &vModelSpaceRayOrig, &vModelSpaceRayDir, &bHit, &dwFace, &fBary1, &fBary2, &fDist, NULL, NULL); if(bHit) m_bHit=false; else m_bHit=true; return m_bHit;}
I NEED HELP, PLEASE!!!!
^__^
THANKS A LOT!!!
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
[edited by - GENTS on June 9, 2004 2:41:43 PM]
There could be other things wrong with the code you''ve posted. For example, you''re using IDirect3DDevice :: GetTransform. This function will only work if you''re using a non-pure device.
What I mean is when you created your original D3D device, if you did NOT use the PURE flag, then using GetTransform is ok. If you DID youse the PURE flag, then you can''t use GetTransform because a pure device does not store the matrices you set.
For the sake of performance, most people use PURE devices and keep track of their own states. If you used a PURE device, then the results from GetTransform are "undefined."
Also, you really should check the return values of the DirectX functions you''re calling to see if any of them fail. When doing any kind of DX development, you should ALWAYS use the Debug Runtime. If you don''t know what I''m talking about, please see the Forum FAQ.
neneboricua
What I mean is when you created your original D3D device, if you did NOT use the PURE flag, then using GetTransform is ok. If you DID youse the PURE flag, then you can''t use GetTransform because a pure device does not store the matrices you set.
For the sake of performance, most people use PURE devices and keep track of their own states. If you used a PURE device, then the results from GetTransform are "undefined."
Also, you really should check the return values of the DirectX functions you''re calling to see if any of them fail. When doing any kind of DX development, you should ALWAYS use the Debug Runtime. If you don''t know what I''m talking about, please see the Forum FAQ.
neneboricua
Ok you''re right!!!
I''ve done a debug check and my D3DXIntersect Function doesn''t return never D3D_OK...
But still now I can''t find the bug of my program!!!
I''ve free memory so I can''t think it''s a less-memory problem!!!
Could anyone help me?!
Im trying to find a solution, but I think it still doesn''t work!!!
THANKS TO EVERYBODY!!!!
(specially to neneboricua19 ^__^ )
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
I''ve done a debug check and my D3DXIntersect Function doesn''t return never D3D_OK...
But still now I can''t find the bug of my program!!!
I''ve free memory so I can''t think it''s a less-memory problem!!!
Could anyone help me?!
Im trying to find a solution, but I think it still doesn''t work!!!
// Check if the ray of the mouse intersect a meshbool SottoTiro(D3DXMESHCONTAINER_EX *Mesh, CCamera cam){ bool m_bHit=FALSE; BOOL bHit; HRESULT hr; D3DXVECTOR3 vPickRayDir; D3DXVECTOR3 vPickRayOrig; D3DXMATRIXA16 matProj; g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &matProj ); D3DXVECTOR3 vModelSpaceRayOrig, vModelSpaceRayDir; LPD3DXBASEMESH pMesh = (LPD3DXBASEMESH) Mesh->pSkinMesh; // Compute the vector of the pick ray in screen space with mouse coords D3DXVECTOR3 v; v.x = ( ( ( 2.0f * MousePoint.x ) / g_WinWidth ) - 1 ) / matProj._11; v.y = -( ( ( 2.0f * MousePoint.y ) / g_WinHeight ) - 1 ) / matProj._22; v.z = 1.0f; // Get the inverse of the composite view and world matrix D3DXMATRIX matView, matWorld, m; hr = g_pD3DDevice->GetTransform( D3DTS_VIEW, &matView ); if( FAILED ( hr ) ) { SetError( "Impossible ottenere D3DTS_VIEW" ); } hr = g_pD3DDevice->GetTransform( D3DTS_WORLD, &matWorld ); if( FAILED ( hr ) ) { SetError( "Impossible ottenere D3DTS_WORLD" ); } m = matWorld * matView; D3DXMatrixInverse( &m, NULL, &m ); // Transform the screen space pick ray into 3D space vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31; vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32; vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33; D3DXVec3Normalize(&vPickRayDir, &vPickRayDir); vPickRayOrig.x = m._41; vPickRayOrig.y = m._42; vPickRayOrig.z = m._43; D3DXMATRIX matInverse; D3DXMatrixInverse(&matInverse, NULL, &Mesh->matCombined ); D3DXVec3TransformCoord(&vModelSpaceRayOrig, &vPickRayOrig, &matInverse); D3DXVec3TransformNormal(&vModelSpaceRayDir, &vPickRayDir, &matInverse); // Collect only the closest intersection hr = D3DXIntersect(pMesh, &vModelSpaceRayOrig, &vModelSpaceRayDir, &bHit, NULL, NULL, NULL, NULL,NULL, NULL); if( hr != D3D_OK ) { SetError( "Impossible to use D3DXIntersect()" ); } if(!bHit) m_bHit=true; else m_bHit=false; return m_bHit;}
THANKS TO EVERYBODY!!!!
(specially to neneboricua19 ^__^ )
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
Below is my picking function to check if the mouse pointer is over the mesh supplied (with it''s world position matrix) as parameters during the function call:
Hope that helps.
BOOL CApp::CheckObjectMouse( ID3DXMesh* Mesh, D3DXMATRIX* ObjMatrix ){ D3DXVECTOR3 vPickRayDir; // Pick ray direction D3DXVECTOR3 vPickRayOrig; // Pick ray origin D3DXVECTOR3 v; // Vector used in computation D3DXMATRIXA16 matProj; // Retrieved projection matrix D3DXMATRIXA16 matView, m; // Retrieved view and computation matrices POINT ptCursor; // Cursor position D3DXVECTOR3 vNear, vDir; D3DXMATRIX invMat; BOOL bHit; DWORD dwIndex; float uCoord, vCoord; float dist; LPDIRECT3DSURFACE9 pBackBuffer = NULL; D3DSURFACE_DESC Desc; // Error check if( m_Graphics.GetDeviceCOM() == NULL ) { return FALSE; } if( Mesh == NULL ) { return FALSE; } if( ObjMatrix == NULL ) { return FALSE; } // Get back buffer description m_Graphics.GetDeviceCOM()->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); pBackBuffer->GetDesc( &Desc ); pBackBuffer->Release(); // Get the projection matrix m_Graphics.GetDeviceCOM()->GetTransform( D3DTS_PROJECTION, &matProj ); // Get the cursor position GetCursorPos( &ptCursor ); // Change coordinates relative to the window which the level is rendered in ScreenToClient( GethWnd(), &ptCursor ); // Compute the pick ray in screen space v.x = ( ( ( 2.0f * ptCursor.x ) / Desc.Width ) - 1 ) / matProj._11; v.y = -( ( ( 2.0f * ptCursor.y ) / Desc.Height ) - 1 ) / matProj._22; v.z = 1.0f; // Get the inverse view matrix m_Graphics.GetDeviceCOM()->GetTransform( D3DTS_VIEW, &matView ); D3DXMatrixInverse( &m, NULL, &matView ); // Transform the screen space pick ray in to 3D coordinates vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31; vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32; vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33; vPickRayOrig.x = m._41; vPickRayOrig.y = m._42; vPickRayOrig.z = m._43; // Calclate the origin as intersection with the near frustum plane vPickRayOrig += vPickRayDir * 1.0f; // Convert the ray to model space D3DXMatrixInverse( &invMat, NULL, ObjMatrix ); D3DXVec3TransformCoord( &vNear, &vPickRayOrig ,&invMat); D3DXVec3TransformNormal( &vDir, &vPickRayDir, &invMat); // Test for intersection D3DXIntersect( Mesh, &vNear, &vDir, &bHit, &dwIndex, &uCoord, &vCoord, &dist, NULL, NULL ); if( bHit == TRUE ) { // Check that we''re close to the object if( dist > 8.0f ) return FALSE; else return TRUE; } else return FALSE;}
Hope that helps.
quote:Original post by GENTS
Ok you''re right!!!
I''ve done a debug check and my D3DXIntersect Function doesn''t return never D3D_OK...
But still now I can''t find the bug of my program!!!
I''ve free memory so I can''t think it''s a less-memory problem!!!
Please use the Debug Runtime. I can''t stress it enough! If you were running with the Debug Runtime, D3D would be able to tell you not only that a function has failed, but also *why* it failed.
neneboricua
There''s even a debug D3DX runtime to link to, use d3dx9d.lib or whatever.
Why you shouldn''t use iostream.h - ever! | A Good free online C++ book
Why you shouldn''t use iostream.h - ever! | A Good free online C++ book
Thanks you all!!!
I'll now try __Daedalus__ code and then I'd say you results!!!
I'm also installing DirectX Debug Runtime for my and your pleasure!!!
Only a last question for __Daedalus__...
But your model matrix is the one of the loading or you pick it during the game just before of the call to your function?!
THANKS A LOT!!!
PS: I've installed the Debug Runtime but it give me no information!!! [except the memory freed - all other is ok! ]
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
[edited by - GENTS on June 11, 2004 7:33:34 AM]
I'll now try __Daedalus__ code and then I'd say you results!!!
I'm also installing DirectX Debug Runtime for my and your pleasure!!!
Only a last question for __Daedalus__...
But your model matrix is the one of the loading or you pick it during the game just before of the call to your function?!
THANKS A LOT!!!
PS: I've installed the Debug Runtime but it give me no information!!! [except the memory freed - all other is ok! ]
-----------------------------------------------
- GENTS -
"Every man dies, not every man really lives"
[William Wallace]
[edited by - GENTS on June 11, 2004 7:33:34 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement