I am currently debugging my code, and since i am using some third party library i need to confirm if my code is doing the right thing so i can find out if it is the source of a bug.
I have bunch of objects, and i have calculated axis aligned bounding box for each, then i frustum cull all and for those that passes this test i take their AABBs corners and transfrom them in screen space and based on that calculate screen space rectangle that i need:
// get 8 corners/points of AABB
void aabb::getCorners(std::array<float3, 8>& corners) const
{
const float3& c = center;
const float3& e = extent; // half extent
corners[0] = float3((c.x - e.x), (c.y - e.y), (c.z - e.z));
corners[1] = float3((c.x + e.x), (c.y - e.y), (c.z - e.z));
corners[2] = float3((c.x - e.x), (c.y + e.y), (c.z - e.z));
corners[3] = float3((c.x + e.x), (c.y + e.y), (c.z - e.z));
corners[4] = float3((c.x - e.x), (c.y - e.y), (c.z + e.z));
corners[5] = float3((c.x + e.x), (c.y - e.y), (c.z + e.z));
corners[6] = float3((c.x - e.x), (c.y + e.y), (c.z + e.z));
corners[7] = float3((c.x + e.x), (c.y + e.y), (c.z + e.z));
}
...
// DirectX like 4x4 matrix
void matrix::projectVector(float3& out, const float3& in, float w, float h) const
{
float norm;
norm = 1.0f / (m03 * in.x + m13 * in.y + m23 * in.z + m33);
out.x = (m00 * in.x + m10 * in.y + m20 * in.z + m30) * norm;
out.y = (m01 * in.x + m11 * in.y + m21 * in.z + m31) * norm;
out.z = (m02 * in.x + m12 * in.y + m22 * in.z + m32) * norm;
out.x = ( out.x + 1.0f ) * w * 0.5f; // + viewport.X, viewport X & Y always 0
out.y = ( 1.0f - out.y ) * h * 0.5f; // + viewport.Y
out.z = ( out.z + 1.0f ) * 0.5f;
}
...
// vp is view * projection,
bool CullingManager::isOccludeeVisible(aabb* pAABB, const matrix& vp)
{
std::array<float3, 8u> in_bboxPts;
std::array<float3, 8u> out_bboxPts;
pAABB->getCorners(in_bboxPts);
float zed = 1.0f; // take closest Z as depth
for(std::size_t i = 0; i < 8u; ++i)
{
vp.projectVector(out_bboxPts, in_bboxPts, (float)occDim.w, (float)occDim.h);
if(zed > out_bboxPts.z)
zed = out_bboxPts.z;
}
// third party library data to fill
OccludeeData od;
od.boundingBox.xMin = std::numeric_limits<int>::max();
od.boundingBox.yMin = std::numeric_limits<int>::max();
od.boundingBox.xMax = std::numeric_limits<int>::min();
od.boundingBox.yMax = std::numeric_limits<int>::min();
for(std::size_t i = 0; i < 8u; ++i)
{
int currentX = (int)out_bboxPts.x;
int currentY = (int)out_bboxPts.y;
if(od.boundingBox.xMin > currentX)
od.boundingBox.xMin = currentX;
if(od.boundingBox.yMin > currentY)
od.boundingBox.yMin = currentY;
if(od.boundingBox.xMax < currentX)
od.boundingBox.xMax = currentX;
if(od.boundingBox.yMax < currentY)
od.boundingBox.yMax = currentY;
}
od.depth = saturate(zed); // clamp 0 - 1
// third party library function
if(!occEngine->testOccludeeVisibility(od))
{
return false;
}
return true;
}
Do you see any problems?
Need more details?
Thank you for your time.