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

Started by
4 comments, last by theone83 14 years, 1 month ago
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?
Advertisement
Seeing some code would be helpful.
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
-- blog: www.fysx.org
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); // 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); // 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); // set the material for the subset
mesh->DrawSubset(i); // draw the subset
}
}
d3ddev->EndScene();

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

}


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.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

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

This topic is closed to new replies.

Advertisement