views:

717

answers:

3

I have a cube rendering inside a Viewport3D and i need to know a way to find out whether ALL of the cube is visible to the user.

Edit:Just to be clear,..I'm not talking about clipping because of the near/far plane distance here. I mean the cube is to tall or wide to fit in the cameras field of view.

Any help would be massively appreciated!

Thanks in advance.

A: 

I can think of doing something similar to this:

Check the nearest point of the cube related to the camera and check if it's being clipped from the near clipping plane. The nearest point from the camera I can think of is one of this points composing the cube. So you have to check each of the 6 points of the cube and check if they are being clipped. If none of them are, then your cube if fully visible Oh, and obviously you have to check against the far clipping plane too.

The code is simple:

for each point of cube do
    if !(point is in farClippingPlane and nearClippingPlane)
       return false;
    end if
end for
return true
Edison Gustavo Muenz
Sorry, I probably should've added that i meant 2D clipping as in the cuboid is too tall for the Viewport. Thanks though
Stimul8d
+1  A: 

I can't offer a solution but I can, perhaps, point you in the right direction.

What you need to get hold of is the extent of the 2D projection of the cube on the view plane. You can then do a simple check on the min and max X & Y values to see whether the whole of the cube is visible.

Adding a tolerance factor to the extent will take care of any rounding errors.

EDIT: I have just done a Google search for "2D projection WPF" and this link came up. It looks like it addresses what you want.

FURTHER EDIT: I've copied the relevant section of code from the above link here.

public static Rect Get2DBoundingBox(ModelVisual3D mv3d)
{
    bool bOK;

    Matrix3D m = MathUtils.TryWorldToViewportTransform(vpv, out bOK);

    bool bFirst = true;    
    Rect r = new Rect();

    if (mv3d.Content is GeometryModel3D)
    {
        GeometryModel3D gm3d = (GeometryModel3D) mv3d.Content;

        if (gm3d.Geometry is MeshGeometry3D)
        {
            MeshGeometry3D mg3d = (MeshGeometry3D)gm3d.Geometry;

            foreach (Point3D p3d in mg3d.Positions)
            {
                Point3D pb = m.Transform(p3d);
                Point p2d = new Point(pb.X, pb.Y);
                if (bFirst)
                {
                    r = new Rect(p2d, new Size(1, 1));
                    bFirst = false;
                }
                else
                {
                    r.Union(p2d);
                }
            }
        }
    }

    return r;
}
ChrisF
+1  A: 

I remember a tutorial on frustum culling on flipcode.

Flipcode - Frustum Culling

I hope it helps.

Stefan Schmidt