#### Archived

This topic is now archived and is closed to further replies.

# Projection Culling Problems

This topic is 5897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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.


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;
}

As always, any help is appreciated.

##### Share on other sites
You are storing the Vectors for the Bounding box, but you should also store a translation vector for the world coordinates to do occlusion testing. So instead your structure should be (assuming you are using AABB)

struct AABB {
VECTOR3 vLower;
VECTOR3 vUpper;
VECTOR3 vWorldTranslation;
};

Mind that if the object rotates you may want to recalculate the box, unless the box initially calculates the size based on full rotation.

struct AABB {
VECTOR3 vLower;
VECTOR3 vUpper;
MATRIX mOrthoMatrix;
};

-------
"Programming is like sex make one mistake, and you have to support it forever."
Homepage: www.ussshrike.com/pcwebvia/

##### Share on other sites
I''m not interested in doing occulsion culling. This test simply takes the 8 points of a bounding box, converts them to screen coordinates, then determines whether or not the contents of the BB are visible on the screen. As far as I know, there is no need to store any additional info for the box other than what I''ve got, as D3DXVec3Project() only needs a vector in world-space coordinates, the current viewport, and the projection, view, and world matrices, all of which are supplied and are valid (I think).

The problem is that from some views, the test belives that the root node of the tree is invisible, which I''m 100% positive is not the case. The values generated by D3DXVec3Project() in these cases are way off from what my math says they should be with the values that I know are being passed... These values are what causes the node to test as invisible...

##### Share on other sites
Heh, I guess I''m one of the few people using projection culling... Sucks for me.

Well, does anyone have any knowledge of how D3DXVec3Project() might be implemented from a mathematical standpoint? My math and what its producing at times just aren''t matching...

As always, any help at all is appreciated.

---Dan

1. 1
2. 2
Rutin
22
3. 3
4. 4
JoeJ
11
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631777
• Total Posts
3002305
×