Sign in to follow this  
theone83

picking and moving an individual object using direct3d and c++

Recommended Posts

theone83    100
i wrote a "detect picking" function using picking rays to select an object from my scene, i'm suffering with moving the object after picking it, i tried changing the world transformation in my rendering function if a hit is detected, then drawing my object, and if no hit is detected my object stays where it is but the problem is that this is not working, and instead of the object moving to another position when hitting it, it keeps blinking appearing and disapearing. any idea what's wrong?

Share this post


Link to post
Share on other sites
fng    154
Could it be that you change the transformation of the object directly? Because if you do then in the next frame the object will no more at the position where your mouse is, so the transformation gets reset and you end up alternating between the two cases.

Cheers,
fng

Share this post


Link to post
Share on other sites
theone83    100
Fire Lancer & fng

I'm a beginner so excuse me
here are some codes

this is my detect picking function

/*********************************************/
/* detect_picking */
/* */
/*********************************************/
void detect_picking()
{
// get the current transform matrices
D3DXMATRIX matProjection, matView, matWorld, matInverse;
d3ddev->GetTransform(D3DTS_PROJECTION, &matProjection);
d3ddev->GetTransform(D3DTS_VIEW, &matView);
d3ddev->GetTransform(D3DTS_WORLD, &matWorld);

// use the mouse coordinates to get the mouse angle
GetCursorPos(&MousePos);
float xAngle = (((2.0f * MousePos.x) / SCREEN_WIDTH) - 1.0f) / matProjection(0, 0);
float yAngle = (((-2.0f * MousePos.y) / SCREEN_HEIGHT) + 1.0f) / matProjection(1, 1);

D3DXVECTOR3 origin, direction;
origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
direction = D3DXVECTOR3(xAngle, yAngle, 1.0f);

// find the inverse matrix
D3DXMatrixInverse(&matInverse, NULL, &(matWorld * matView));

// convert origin and direction into model space
D3DXVec3TransformCoord(&origin, &origin, &matInverse);
D3DXVec3TransformNormal(&direction, &direction, &matInverse);
D3DXVec3Normalize(&direction, &direction);

// detect picking
D3DXIntersect(mesh, &origin, &direction, &hit, NULL, NULL, NULL, NULL, NULL, NULL);
}

hit is defines globally

this is my render function

void render_frame(void)
{
//create a RECT to contain the text
static RECT textbox;
SetRect(&textbox, 0, 0, 400, 200); //(&textbox, 0, 0, 640, 480)

detect_picking();

d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

d3ddev->BeginScene();

// set the view transform
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (-2.0f, -12.0f, -8.0f), // the camera position
&D3DXVECTOR3 (-2.0f, 0.0f, 0.0f), // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction
d3ddev->SetTransform(D3DTS_VIEW, &matView);

// set the projection transform
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(45),
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT,
1.0f, // the near view-plane
1000.0f); // the far view-plane
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);

static float index = 0.0f; // index+=0.03f;

// collect keyboard data
if(KEY_DOWN(VK_LEFT)) index += 0.03f;
if(KEY_DOWN(VK_RIGHT)) index -= 0.03f;

// set the world transform
D3DXMATRIX matRotateY;
D3DXMatrixRotationY(&matRotateY, index);
d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));


//draw the apple
for(DWORD i = 0; i < numMaterials; i++) // loop through each subset
{
d3ddev->SetMaterial(&material[i]); // set the material for the subset
mesh->DrawSubset(i); // draw the subset
}

if(hit)
{
D3DXMATRIX matTranslate;
D3DXMatrixTranslation(&matTranslate, 0.0f, 50.0f, 0.0f);
d3ddev->SetTransform(D3DTS_WORLD, &matTranslate);

//draw the apple
for(DWORD i = 0; i < numMaterials; i++) // loop through each subset
{
d3ddev->SetMaterial(&material[i]); // set the material for the subset
mesh->DrawSubset(i); // draw the subset
}

//draw the text
font->DrawText(NULL,
L"Apple",
22,
&textbox,
DT_CENTER | DT_VCENTER,
D3DCOLOR_ARGB(255, 255, 255, 255));

}

else
{
//draw the apple
for(DWORD i = 0; i < numMaterials; i++) // loop through each subset
{
d3ddev->SetMaterial(&material[i]); // set the material for the subset
mesh->DrawSubset(i); // draw the subset
}
}
d3ddev->EndScene();

d3ddev->Present(NULL, NULL, NULL, NULL);

}


Share this post


Link to post
Share on other sites
Buckeye    10747
You're drawing the apple twice during each render. I'm not sure that's what you want to do. You draw the apple the first time with a "rotate" world matrix. If there's a hit, you render it with a "translate" world matrix. If there's no hit, you render the apple again.

Perhaps you could explain what you'd like to see happen.

Also, you have a lot of interaction among the various matrices you're using because you call detect_picking before you set the projection/view/world, etc., for the render, so your pick routine is using those matrices (particularly the world transfrom) from the previous render.

Share this post


Link to post
Share on other sites
theone83    100
hello Buckeye

I want to change the apple's position when the mouse hits it, that's it.

I draw it twice because i need the draw function inside the if(hit){} but at the same time leaving it there prevents the apple from appearing at the beginning.
again i'm a beginner so bear with me please:) thanks

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