Original Post
I''m working on a projection culling system that uses points from a bounding box to determine whether the box is visible. I''m using it with a quadtree right now with mixed results. For the most part, it functions as expected with no problems, but certain values for the view matrix causes D3DXVec3Project() to produce what have to be erroneous values. I doubt the function is bugged, so I have spent the last week combing my code for errors. I''ve stepped through my code with the VS.NET debugger so many times that I''ve lost count. Unfortunately, I''ve not found the problem. =(
I normally don''t post code and ask people to help me debug it, but I''m fresh out of ideas and I hope that maybe someone on here can see something obvious that I skipped. I''ve ommitted all of the code that doesn''t have anything to do with the actual culling, but if anyone needs to see more, let me know and I''ll post it.
As always, any help is appreciated.
struct BOUNDINGBOX
{
D3DXVECTOR3 point1; //The lower-left front corner of the box
D3DXVECTOR3 point2; //The upper-right back corner of the box
};
//Structure that can store visibility information for a point/object
//-If an item is 0, it is within the screen dimmensions on that axis
//-If an item is -1, it is less than the minimum value for that dimmension
//-If an item is +1, it is greater than the maximum value for that dimmension
struct VISIBILITY_INFO
{
int vertical;
int horizontal;
};
inline operator == (VISIBILITY_INFO info1, VISIBILITY_INFO info2)
{
return (info1.horizontal == info2.horizontal) && (info1.vertical == info2.vertical);
}
VISIBILITY_INFO CCamera::GetMappedLocation(D3DXVECTOR3 vector)
{
D3DXVECTOR3 screenVector; //The location the vector will be mapped to
VISIBILITY_INFO info; //The structure that is returned
//Determine where the specified vector will be mapped
D3DXVec3Project(&screenVector,&vector,&viewPort,&projectionTransform,&viewTransform,&worldTransform);
//If the point is less than the minimum X value
if(screenVector.x < viewPort.X)
info.horizontal = -1;
//If the point is greater than the maximum X value
else if(screenVector.x > viewPort.Width)
info.horizontal = 1;
//Else the point is visible horizontally
else
info.horizontal = 0;
//If the point is less than the minimum Y value
if(screenVector.y < viewPort.Y)
info.vertical = -1;
//If the point is greater than the maximum Y value
else if(screenVector.y > viewPort.Height)
info.vertical = 1;
//Else the point is visible vertically
else
info.vertical = 0;
return info;
}
//Returns non-zero if the box is visible on the screen, 0 otherwise
int CCamera::CheckVisibility(BOUNDINGBOX box)
{
VISIBILITY_INFO locations[8]; //The locations of the 6 bounding box coordinates
//0 - front top right
//1 - front bottom right
//2 - front bottom left
//3 - front top left
//4 - back top right
//5 - back bottom right
//6 - back bottom left
//7 - back top left
//Get the location types
locations[0] = GetMappedLocation(D3DXVECTOR3(box.point2.x,box.point2.y,box.point1.z));
locations[1] = GetMappedLocation(D3DXVECTOR3(box.point2.x,box.point1.y,box.point1.z));
locations[2] = GetMappedLocation(box.point1);
locations[3] = GetMappedLocation(D3DXVECTOR3(box.point1.x,box.point2.y,box.point1.z));
locations[4] = GetMappedLocation(box.point2);
locations[5] = GetMappedLocation(D3DXVECTOR3(box.point2.x,box.point1.y,box.point2.z));
locations[6] = GetMappedLocation(D3DXVECTOR3(box.point1.x,box.point1.y,box.point2.z));
locations[7] = GetMappedLocation(D3DXVECTOR3(box.point1.x,box.point2.y,box.point2.z));
//If all points are equal, they are all in the same quadrant
if(locations[0] == locations[1] &&
locations[1] == locations[2] &&
locations[2] == locations[3] &&
locations[3] == locations[4] &&
locations[4] == locations[5] &&
locations[5] == locations[6] &&
locations[6] == locations[7])
{
//if the points are visible
if(locations[0].horizontal == 0 && locations[0].vertical == 0)
return 1;
//else they are all invisible
else
return 0;
}
//If all the points are all above the screen
//A bitwise operation can be used to determine whether all values are -1
if((locations[0].vertical & locations[1].vertical & locations[2].vertical &
locations[3].vertical & locations[4].vertical & locations[5].vertical &
locations[6].vertical & locations[7].vertical) == -1)
return 0;
//else if they are all below the screen
//No bitwise operation will work on this check
else if(locations[0].vertical == locations[1].vertical &&
locations[1].vertical == locations[2].vertical &&
locations[2].vertical == locations[3].vertical &&
locations[3].vertical == locations[4].vertical &&
locations[4].vertical == locations[5].vertical &&
locations[5].vertical == locations[6].vertical &&
locations[6].vertical == locations[7].vertical &&
locations[7].vertical == 1)
return 0;
//else if they are all to the left of the screen
//A bitwise operation can be used to determine whether all values are -1
else if((locations[0].horizontal & locations[1].horizontal & locations[2].horizontal &
locations[3].horizontal & locations[4].horizontal & locations[5].horizontal &
locations[6].horizontal & locations[7].horizontal) == -1)
return 0;
//else if they are all to the right of the screen
//No bitwise operation can be used to determine whether all values are -1
else if(locations[0].horizontal == locations[1].horizontal &&
locations[1].horizontal == locations[2].horizontal &&
locations[2].horizontal == locations[3].horizontal &&
locations[3].horizontal == locations[4].horizontal &&
locations[4].horizontal == locations[5].horizontal &&
locations[5].horizontal == locations[6].horizontal &&
locations[6].horizontal == locations[7].horizontal &&
locations[7].horizontal == 1)
return 0;
//Else they occupy more than one extreme and may still be visible
else
return 1;
return 0;
}