Picking World*Projection

Started by
5 comments, last by iedoc 12 years, 3 months ago
if my shader is set to this in the .fx
[font="Consolas"][size="2"][font="Consolas"][size="2"]Transform = mul(World, Projection); = World*Projection[/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"]what space should the ray be in?[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"]i have tried this[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"]D3DXMatrixInverse(&matInverse, NULL, &(matWorld * matProjection));[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"]but it dosent pick , also another question i have is why does the z work diferent when rendering something thats connected to the projection , etc[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"]this is the value of "World" set in the shader[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"] [/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"]D3DXMatrixTranslation(&matWorld,0.0f,0.0f,5.0f); //why wouldnt this be negative to value to make it go backs from the screen , why is it oposite?[/font][/font][/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"]effect->SetMatrix([/font][/font][font="Consolas"][size="2"][color="#a31515"][font="Consolas"][size="2"][color="#a31515"][font="Consolas"][size="2"][color="#a31515"]"World"[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"], &(matRotateY*matWorld));[/font][/font][/font][/font][/font][/font]
:)
Advertisement
if i understand your question correctly, then it is because direct3d uses a left hand coordinate system, which means that the z axis going "into" the screen or "away" from the camera is positive, so if your camera is set at the point (0,0,0) in the world, and looking down the +z axis, objects that are -z will be behind the camera, +z in front of the camera, -x left of the camera, +x right of the camera, -y below the camera, and +y above the camera.

btw, you should be doing world * view * projection. is your projection view*projection?

for picking to work, first you transform the pick from 2d screen space to 3d world space. first you get the pick in 2d screen space, and transform it into a 3d ray using the projection matrix. after you have a 3d ray, you transform the 3d ray into world space (where all the objects in the scene are) by multiplying it with the inverse view matrix (camera's matrix). you can do it like this:

//Transform 2D pick position on screen space to 3D ray in View space



D3DXVECTOR3 pickRayViewSpace;
pickRayViewSpace.x = ((( 2.0f * mouseX) / ClientWidth ) - 1 ) / Projection(0,0);
pickRayViewSpace.y = -((( 2.0f * mouseY) / ClientHeight) - 1 ) / Projection(1,1);
pickRayViewSpace.z = 1.0f;

D3DXVECTOR3 pickRayViewSpacePos(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 pickRayViewSpaceDir(pickRayViewSpace.x, pickRayViewSpace.y, pickRayViewSpace.z);
// Transform 3D Ray from View space to 3D ray in World space
D3DXMATRIX pickRayWorldSpace;
D3DXMatrixInverse(&pickRayWorldSpace, 0, &View);

D3DXVec3TransformCoord(&pickRayViewSpacePos, &pickRayViewSpacePos, &pickRayWorldSpace);
D3DXVec3TransformNormal(&pickRayViewSpaceDir, &pickRayViewSpaceDir, &pickRayWorldSpace);


[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

Then you have to transform the world space pick ray into object space, which is the inverse of the objects world space matrix:[/font]




D3DXMatrixInverse(&pickRayLocalSpace,NULL,&ObjectLocalSpace);

D3DXVECTOR3 pickRayLocalSpacePos,pickRayLocalSpaceDir;

D3DXVec3TransformCoord(&pickRayLocalSpacePos,&pickRayViewSpacePos,&pickRayLocalSpace);
D3DXVec3TransformNormal(&pickRayLocalSpaceDir,&pickRayViewSpaceDir,&pickRayLocalSpace);

D3DXVec3Normalize(&pickRayLocalSpaceDir,&pickRayLocalSpaceDir);


maybe this could help:

http://braynzarsoft....x.php?p=Picking
If it helps, here is my code to detect picking:
void Editor::updatePickingRay()
{
D3DXMATRIX matProjection, matView;
framework->getD3DDev()->SetTransform(D3DTS_VIEW, &matView);

GetCursorPos(&MousePos);

POINT ptCursor;
GetCursorPos(&ptCursor);
ScreenToClient(framework->getHwnd(), &ptCursor);

D3DXVECTOR3 v;
v.x = (((2.0f * ptCursor.x) / viewPort.Width ) - 1) / matProjection._11;
v.y = -(((2.0f * ptCursor.y) / viewPort.Height) - 1) / matProjection._22;
v.z = 1.0f;

D3DXMATRIX m;
D3DXMatrixInverse(&m, NULL, &matView);

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;

vPickRayOrig += vPickRayDir;
}

vPickRayOrig and vPickRayDir are both D3DXVECTOR3.
And for detecting picking on a quad I use:
D3DXVec3TransformCoord(&vert1, &vert1, &matFinal);
D3DXVec3TransformCoord(&vert2, &vert2, &matFinal);
D3DXVec3TransformCoord(&vert3, &vert3, &matFinal);
D3DXVec3TransformCoord(&vert4, &vert4, &matFinal);


bool hit = D3DXIntersectTri(
&vert1,
&vert2,
&vert3, &vPickRayOrig, &vPickRayDir, NULL, NULL, NULL) |
D3DXIntersectTri(
&vert2,
&vert3,
&vert4, &vPickRayOrig, &vPickRayDir, NULL, NULL, NULL);

if(hit)
{
//Do stuff here
}

Vert1, 2, 3 and 4 are the vertices of the quad, matFinal is the matrix that has had the world space transformations applied to it (e.g. using D3DXMatrixTranslation, etc).
Not sure if this will be of any help to you.
I know how todo it like that, its just for an object that moves with the camera like in a fps game, i want to pick that object or is that impossible, to render a weapon for an fps game it needs to be World*Projection , with z+ going in to the screen like you said

heres my little diagram in picture

wprojpic.jpg
:)
I guess i don't really understand what your asking. Are you wondering how to basically toss the gun in the direction the camera is facing?

when you say World*Projection, is "World" the weapons position in world space? or the camera's position in world space? i don't think it would really work to multiply the objects position in world space directly with the projection matrix.

are you wondering about using the mouse to pick the gun? because i think that's what picking usually means, using the mouse to pick an object on the screen
I know how to pick an object thats rendered with World*View*Projection , i am curious if you can pick objects thats Rendered with World*Projecion, IE Translation matrix multiplied by Projection Fov.
:)
AAH, i think i got you now, sorry, must have been a brain fart, haha. you are rendering your weapon directly to the screen without even taking the camera's (or the entire worlds) space into account. yes, this is possible. in fact, it would make picking even more simple. all you have to do is skip the step where you transform the picking ray into world space and transform it directly into object space. So, i hope this is right, i'm a little tired so maybe i'm just wrong again, but you could try this:


//Transform 2D pick position on screen space to 3D ray in View space
D3DXVECTOR3 pickRayViewSpace;
pickRayViewSpace.x = ((( 2.0f * mouseX) / ClientWidth ) - 1 ) / Projection(0,0);
pickRayViewSpace.y = -((( 2.0f * mouseY) / ClientHeight) - 1 ) / Projection(1,1);
pickRayViewSpace.z = 1.0f;

D3DXVECTOR3 pickRayViewSpacePos(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 pickRayViewSpaceDir(pickRayViewSpace.x, pickRayViewSpace.y, pickRayViewSpace.z);

// Skip transforming it into world space
// Transform 3D Ray from View space to 3D ray in World space
// D3DXMATRIX pickRayWorldSpace;
// D3DXMatrixInverse(&pickRayWorldSpace, 0, &View);

// D3DXVec3TransformCoord(&pickRayViewSpacePos, &pickRayViewSpacePos, &pickRayWorldSpace);
// D3DXVec3TransformNormal(&pickRayViewSpaceDir, &pickRayViewSpaceDir, &pickRayWorldSpace);

// transform directly into object space
D3DXMatrixInverse(&pickRayLocalSpace,NULL,&ObjectLocalSpace);
D3DXVECTOR3 pickRayLocalSpacePos,pickRayLocalSpaceDir;

D3DXVec3TransformCoord(&pickRayLocalSpacePos,&pickRayViewSpacePos,&pickRayLocalSpace);
D3DXVec3TransformNormal(&pickRayLocalSpaceDir,&pickRayViewSpaceDir,&pickRayLocalSpace);


D3DXVec3Normalize(&pickRayLocalSpaceDir,&pickRayLocalSpaceDir);


I hope that's right. now that i'm looking at it though, the vector names at the beginning are misleading... they should actually be named projection instead of view

well, either way, I hope i'm not just wrong again, haha, i always get a little embarrassed giving incorrect information ;)

This topic is closed to new replies.

Advertisement