Sign in to follow this  

Plane & View Frustum Classification

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can someone explain how to classify a viewing frustum with respect to a plane in DirectX. I can classify a vector with respect to a plane easily enough, but I don't know how to handle the odd shape of the frustum i.e. I have a camera with a Far/Near Clipping plane, an Up vector, a Target vector, a Position vector and a field of view and I have a plane. I want to know if the frustum is infront, behind or spanning the plane. I can't seem to find anything on how this is acheived. Thank you, Chris

Share this post


Link to post
Share on other sites
Keep in mind that the view frustum is really just a representation (in world space) of what ends up being contained in screen space after all transforms have been performed.

With that said, consider why the frustum is shaped the way that it is. The near plane and the far plane are the same shape (rectangles proportional to the screen dimensions), but the far plane is much larger. But after a scene is tranformed and put into screen space, the near and far plane end up as the same size. This is due to the perspective transform, which essentially applies an aspect ratio for your scene.

So, what does this have to do with your question you ask? You need to use your perspective matrix along with your view matrix to determine the world space shape of the frustum. Google for "Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix" written by Gil Gribb and Klaus Hartmann. Its a quick and straight forward method to get a description of the six planes of the view frustum.

Once you have the frustum representation (essentially just six planes), you can simply perform plane to plane tests to determine frustum position relative to a plane or vice versa.

If you still have trouble understanding or have more questions, post again. I had trouble getting it at first, but once you "see" it, it makes a lot of sense.

Hope this helps,

Jason Z

Share this post


Link to post
Share on other sites
Excellent Jason! I did what you said, found the article thanks, it was just what I needed! Anyway, I put bounding boxes through my tree and I generate the frustum planes every frame. It sort of works, if I am looking straight at an object it thinks it is within the planes, but if I move the camera slightly the the top, side etc the object is classified as outside the frustum. I've checked stuff over but I can't seem to figure out where I'm going wrong. You had anything like this ?

Thanks,

Chris

Share this post


Link to post
Share on other sites
ugh, i've been bashing at this for hours now with only half luck. I'm going to post what I've done and can you try and tell me where I'm going wrong.

Ok here goes, for my plane extraction I'm doing the following:



Matrix PV = m_ViewMatrix * m_ProjectionMatrix;

// Left Plane
m_LeftPlane.A = PV.M14 + PV.M11;
m_LeftPlane.B = PV.M24 + PV.M21;
m_LeftPlane.C = PV.M34 + PV.M31;
m_LeftPlane.D = PV.M44 + PV.M41;


// Right Plane
m_RightPlane.A = PV.M14 - PV.M11;
m_RightPlane.B = PV.M24 - PV.M21;
m_RightPlane.C = PV.M34 - PV.M31;
m_RightPlane.D = PV.M44 - PV.M41;

// Bottom Plane
m_BottomPlane.A = PV.M14 + PV.M12;
m_BottomPlane.B = PV.M24 + PV.M22;
m_BottomPlane.C = PV.M34 + PV.M32;
m_BottomPlane.D = PV.M44 + PV.M42;

// Top Plane
m_TopPlane.A = PV.M14 - PV.M12;
m_TopPlane.B = PV.M24 - PV.M22;
m_TopPlane.C = PV.M34 - PV.M32;
m_TopPlane.D = PV.M44 - PV.M42;

// Near Plane
m_NearPlane.A = PV.M13;
m_NearPlane.B = PV.M23;
m_NearPlane.C = PV.M33;
m_NearPlane.D = PV.M43;

// Far Plane
m_FarPlane.A = PV.M14 - PV.M13;
m_FarPlane.B = PV.M24 - PV.M23;
m_FarPlane.C = PV.M34 - PV.M33;
m_FarPlane.D = PV.M44 - PV.M43;







just like the article explained that you directed me to.

I have created bounding boxes around my nodes in my BSP tree, I've been testing with a simple cube which is contained in its own node, so no split polygons and I manually checked the generate bounding box, it matches the size of the cube it encompasses, so no problems there.

When I come to test the box against the frustums i do the following:


public bool CheckBox(BoundingBox box)
{
// Check the 8 corners of the box, if any point is within the frustum
// we will have to return true.

for (int i = 0; i < 8; i++)
{
if (CheckPoint(box.Corners[i]))
return true;
}

// No points were inside the frustum
return false;
}

public bool CheckPoint(Vector3 point)
{

if (SpacePartition.ClassifyPoint(m_LeftPlane, point, m_PlaneThickness) == Side.Behind)
return false;

if (SpacePartition.ClassifyPoint(m_RightPlane, point, m_PlaneThickness) == Side.Behind)
return false;

if (SpacePartition.ClassifyPoint(m_TopPlane, point, m_PlaneThickness) == Side.Behind)
return false;

if (SpacePartition.ClassifyPoint(m_BottomPlane, point, m_PlaneThickness) == Side.Behind)
return false;

if (SpacePartition.ClassifyPoint(m_NearPlane, point, m_PlaneThickness) == Side.Behind)
return false;

if (SpacePartition.ClassifyPoint(m_FarPlane, point, m_PlaneThickness) == Side.Behind)
return false;


return true;
}







SpacePartition.ClassifyPoint just does the standard Ax + By +Cz + D = 0 test and returns which side the point is in. Based on the return value of CheckBox i decide whether to draw the cube or not.

Currently I get strange effects, like the cube will be visble and then I move slightly left and it vanishes. It almost seems like one of my planes is through the center of the screen :/ But I've checked the plane extractions over and over, they seem ok.

Please help if you can I'm totally at an ends. If there is ANY other info u need to understand my problem pls say.

Thank you very much for your help,

Chris

Share this post


Link to post
Share on other sites
Your code for calculating the view frustum and then checking a bounding box looks correct. This would mean your bounding box information must be incorrect. The problem you are describing sounds similiar to what would happen if your 'y' values for the bounding box corners were set incorrectly. Are you insuring that your values for the bounding box are set correctly? IE- you need to traverse through every vertex inside a bounding box and determine the highest and lowest points - you can't just set the y value of the top right point to be the y value of the top right vertex for example. This is also assuming your bounding boxes are axis aligned.

Share this post


Link to post
Share on other sites
I'm pretty sure my bounding boxes are correct. Heres the code to create them:


private BoundingBox BuildBoundingBox(PolygonNode node)
{
BoundingBox box = new BoundingBox(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue, float.MaxValue, float.MinValue);
BoundingBox behind = new BoundingBox(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue, float.MaxValue, float.MinValue);
BoundingBox infront = new BoundingBox(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue, float.MaxValue, float.MinValue);

// Get our childs to generate their boxes
if (node.Behind != null)
behind = BuildBoundingBox(node.Behind);

if (node.Infront != null)
infront = BuildBoundingBox(node.Infront);

// Choose the largest properties from each of our bounding boxes
box.Left = (behind.Left < infront.Left) ? behind.Left : infront.Left;

box.Right = (behind.Right > infront.Right) ? behind.Right : infront.Right;

box.Bottom = (behind.Bottom < infront.Bottom) ? behind.Bottom : infront.Bottom;

box.Top = (behind.Top > infront.Top) ? behind.Top : infront.Top;

box.Front = (behind.Front < infront.Front) ? behind.Front : infront.Front;

box.Back = (behind.Back > infront.Back) ? behind.Back : infront.Back;

// If we have no data, just return the box
if (node.Polygons == null)
return box;

for (int i = 0; i < node.Polygons.Length; i++)
{
for (int j = 0; j < node.Polygons[i].Points.Count; j++)
{
Vector3 vertex = ((VertexPNT) m_Verticies[node.Polygons[i].Points[j]]).Position;

// Left
if (vertex.X < box.Left)
box.Left = vertex.X;

// Right
if (vertex.X > box.Right)
box.Right = vertex.X;

// Bottom
if (vertex.Y < box.Bottom)
box.Bottom = vertex.Y;

// Top
if (vertex.Y > box.Top)
box.Top = vertex.Y;

// Front
if (vertex.Z < box.Front)
box.Front = vertex.Z;

// Back
if (vertex.Z > box.Back)
box.Back = vertex.Z;
}
}

// Store the bounding box for this node and generate the corners
box.Generate();
node.Bounds = box;

return box;
}



I've checked it over, maybe something I can't see... The box.Generate() creates a set of verticies for the corners of the box:


public void Generate()
{
if (m_Corners == null)
m_Corners = new Vector3[8];

m_Corners[0] = new Vector3(Left, Top, Front); // Front, Top, Left
m_Corners[1] = new Vector3(Left, Bottom, Front); // Front, Bottom, Left
m_Corners[2] = new Vector3(Right, Bottom, Front); // Front, Bottom, Right
m_Corners[3] = new Vector3(Right, Top, Front); // Front, Top, Right

m_Corners[4] = new Vector3(Left, Top, Back); // Back, Top, Left
m_Corners[5] = new Vector3(Left, Bottom, Back); // Back, Bottom, Left
m_Corners[6] = new Vector3(Right, Bottom, Back); // Back, Bottom, Right
m_Corners[7] = new Vector3(Right, Top, Back); // Back, Top, Right
}



Hmmm.... still pulling hair out here, I know its something simple but I just can't find it :/

Thanks for your reply

Chris

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this