I am trying to draw 2D axis aligned rect around my 3D teapot object.
I cant get correct results and do not know what i am doing wrong.
1. Load teapot and calculate bbox
struct BBox
{
D3DXVECTOR3 minPt;
D3DXVECTOR3 maxPt;
};
BBox bBox;
...
hr = D3DXLoadMeshFromX("Teapot.x", D3DXMESH_MANAGED, d3d9device, 0, 0, 0, 0, &teapotMesh);
if(FAILED(hr))
{
MessageBox(0, TEXT("Failed to load teapot mesh!"), 0, 0);
return false;
}
BYTE* pData = 0;
teapotMesh->LockVertexBuffer(0, (LPVOID*)&pData);
hr = D3DXComputeBoundingBox((D3DXVECTOR3*)pData, teapotMesh->GetNumVertices(), teapotMesh->GetNumBytesPerVertex(), &bBox.minPt, &bBox.maxPt);
if(FAILED(hr))
{
MessageBox(0, TEXT("Failed to compute bbox!"), 0, 0);
return false;
}
teapotMesh->UnlockVertexBuffer();
2. get 8 points of a bbox function
std::array<D3DXVECTOR3, 8> GetBBoxCorners(const BBox& bb)
{
std::array<D3DXVECTOR3, 8> out;
D3DXVECTOR3 c = (bb.minPt + bb.maxPt) * 0.5f;
D3DXVECTOR3 e = (bb.maxPt - bb.minPt) * 0.5f;
out[0] = D3DXVECTOR3((c.x - e.x), (c.y - e.y), (c.z - e.z));
out[1] = D3DXVECTOR3((c.x + e.x), (c.y - e.y), (c.z - e.z));
out[2] = D3DXVECTOR3((c.x - e.x), (c.y + e.y), (c.z - e.z));
out[3] = D3DXVECTOR3((c.x + e.x), (c.y + e.y), (c.z - e.z));
out[4] = D3DXVECTOR3((c.x - e.x), (c.y - e.y), (c.z + e.z));
out[5] = D3DXVECTOR3((c.x + e.x), (c.y - e.y), (c.z + e.z));
out[6] = D3DXVECTOR3((c.x - e.x), (c.y + e.y), (c.z + e.z));
out[7] = D3DXVECTOR3((c.x + e.x), (c.y + e.y), (c.z + e.z));
return out;
}
3. Draw teapot
effect->SetTechnique("tTech");
effect->Begin(0, 0);
effect->BeginPass(0);
D3DXVECTOR3 pos(0.0f, 1.0f, 4.0f);
D3DXMATRIX teapotMat;
D3DXMatrixTranslation(&teapotMat, pos.x, pos.y, pos.z);
D3DXMATRIX worldViewProj = teapotMat * cam->getView() * cam->getProjection();
effect->SetMatrix("WorldViewProjection", &worldViewProj);
effect->SetTexture("DiffuseTex", teapotTexture);
effect->CommitChanges();
teapotMesh->DrawSubset(0);
effect->EndPass();
effect->End();
4. Transform 8 bbox points and find 2d min/max rect
bBox.maxPt += pos;
bBox.minPt += pos;
auto bboxPts = GetBBoxCorners(bBox);
auto ptCnt = bboxPts.size();
decltype(bboxPts) outPts;
D3DVIEWPORT9 vp;
d3d9device->GetViewport(&vp);
for(std::size_t i = 0; i < ptCnt; ++i)
{
D3DXVec3Project(&outPts, &bboxPts, &vp, &cam->getProjection(), &cam->getView(), &teapotMat);
}
struct BBox2D
{
D3DXVECTOR2 minPt;
D3DXVECTOR2 maxPt;
};
BBox2D bb2D;
bb2D.minPt = D3DXVECTOR2(std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
bb2D.maxPt = D3DXVECTOR2(std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
for(std::size_t i = 0; i < ptCnt; ++i)
{
if(bb2D.minPt.x > outPts.x)
{
bb2D.minPt.x = outPts.x;
}
if(bb2D.minPt.y > outPts.y)
{
bb2D.minPt.y = outPts.y;
}
if(bb2D.maxPt.x < outPts.x)
{
bb2D.maxPt.x = outPts.x;
}
if(bb2D.maxPt.y < outPts.y)
{
bb2D.maxPt.y = outPts.y;
}
}
struct DEBUG_VERTEX
{
D3DXVECTOR4 p;
DWORD color;
};
std::array<DEBUG_VERTEX, 8> linePts;
for(std::size_t i = 0; i < ptCnt; ++i)
{
linePts.color = D3DCOLOR_XRGB(255, 0, 0);
}
float z = 0.5f;
float w = 1.0f;
linePts[0].p = D3DXVECTOR4(bb2D.minPt.x, bb2D.minPt.y, z, w);
linePts[1].p = D3DXVECTOR4(bb2D.maxPt.x, bb2D.minPt.y, z, w);
linePts[2].p = D3DXVECTOR4(bb2D.maxPt.x, bb2D.minPt.y, z, w);
linePts[3].p = D3DXVECTOR4(bb2D.maxPt.x, bb2D.maxPt.y, z, w);
linePts[4].p = D3DXVECTOR4(bb2D.maxPt.x, bb2D.maxPt.y, z, w);
linePts[5].p = D3DXVECTOR4(bb2D.minPt.x, bb2D.maxPt.y, z, w);
linePts[6].p = D3DXVECTOR4(bb2D.minPt.x, bb2D.maxPt.y, z, w);
linePts[7].p = D3DXVECTOR4(bb2D.minPt.x, bb2D.minPt.y, z, w);
d3d9device->SetTransform(D3DTS_PROJECTION, &cam->getProjection());
d3d9device->SetTransform(D3DTS_VIEW, &cam->getView());
d3d9device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
d3d9device->DrawPrimitiveUP(D3DPT_LINELIST, linePts.size() / 2, &linePts[0], sizeof(DEBUG_VERTEX));
Can you spot what i am doing wrong?
If you need more info please tell.
Thank you for your time.