Permalink
Browse files

Deleted empty Geometry.cpp file.

Camera:
  - added frustumPlanes()
  - frustumCorners() are now returned in ccw order.

Geometry:
  - Added FrustumUtils for frustum tests.
  • Loading branch information...
1 parent e03c7cc commit cb69335fc8b6b1382b9261e43e603155d215cde9 Jiawen Chen committed May 4, 2012
View
8 core/include/cameras/Camera.h
@@ -2,6 +2,7 @@
#include <vector>
+#include <geometry/Plane3f.h>
#include <vecmath/Vector2i.h>
#include <vecmath/Vector2f.h>
#include <vecmath/Vector3f.h>
@@ -33,8 +34,15 @@ class Camera
bool* pbZFarIsInfinite = nullptr ) const;
// return the 8 corners of the camera frustum
+ // 0-3 are the near plane, in ccw order
+ // 4-7 are the far plane, in ccw order
std::vector< Vector3f > frustumCorners() const;
+ // return the 6 planes of the camera frustum
+ // in the order: left, bottom, right, top, near, far
+ // all the planes have normals pointing outward
+ std::vector< Plane3f > frustumPlanes() const;
+
bool isZFarInfinite();
void setFrustum( float left, float right,
View
2 core/include/geometry/BoundingBox3f.h
@@ -46,6 +46,8 @@ class BoundingBox3f
// returns the maximum of the lengths of the 3 sides of this box
float longestSideLength() const;
+ // returns the 8 corners of the bounding box
+ // in the hypercube ordering (x changes most frequently, y next, then z)
std::vector< Vector3f > corners() const;
// enlarges the box if p is outside it
View
30 core/include/geometry/FrustumUtils.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <cassert>
+#include "geometry/BoundingBox3f.h"
+#include "geometry/Plane3f.h"
+
+#include <vector>
+#include "vecmath/Vector3f.h"
+
+class FrustumUtils
+{
+public:
+
+ enum IntersectionResult
+ {
+ INSIDE,
+ OUTSIDE,
+ INTERESECTING
+ };
+
+ // *conservatively* tests whether a box intersects a *convex* set of planes defined by a camera frustum
+ // (by testing the 8 corners of the box against all 6 planes)
+ //
+ // the test is conservative in the sense that:
+ // it's guaranteed to return INSIDE if the box is inside
+ // it's guaranteed to return INTERESECTING if the box straddles the frustum
+ // it *usually* returns OUTSIDE if it's outside, but in some cases, may return INTERSECTING
+ static IntersectionResult intersectBoundingBox( const BoundingBox3f& box, Plane3f planes[ 6 ] );
+
+};
View
6 core/include/geometry/Plane3f.h
@@ -1,5 +1,4 @@
-#ifndef PLANE_3F_H
-#define PLANE_3F_H
+#pragma once
#include <vecmath/Matrix3f.h>
#include <vecmath/Vector3f.h>
@@ -43,6 +42,7 @@ class Plane3f
Vector3f closestPointOnPlane( const Vector3f& p ) const;
// Returns the *signed* shortest distance between p and the plane.
+ // distance is positive on the same side as the normal
float distance( const Vector3f& p ) const;
// Returns the point on the plane closest to the origin
@@ -81,5 +81,3 @@ class Plane3f
float c;
float d;
};
-
-#endif // PLANE_3F_H
View
40 core/src/cameras/Camera.cpp
@@ -56,23 +56,49 @@ void Camera::getFrustum( float* pfLeft, float* pfRight,
std::vector< Vector3f > Camera::frustumCorners() const
{
- std::vector< Vector3f > out( 8 );
+ std::vector< Vector3f > corners( 8 );
Vector4f cubePoint( 0.f, 0.f, 0.f, 1.f );
- Matrix4f invProj = inverseViewProjectionMatrix();
+ Matrix4f invViewProj = inverseViewProjectionMatrix();
// take the NDC cube and unproject it
for( int i = 0; i < 8; ++i )
{
+ // so vertices go around in order counterclockwise
+ cubePoint[0] = ( ( i & 1 ) ^ ( ( i & 2 ) >> 1 ) ? 1.f : -1.f );
cubePoint[1] = ( i & 2 ) ? 1.f : -1.f;
- cubePoint[0] = ( ( i & 1 ) ? 1.f : -1.f ) * cubePoint[1]; // so vertices go around in order
- // cubePoint[2] = ( i & 4 ) ? 1.f : ( m_directX ? 0.f : -1.f );
- cubePoint[2] = ( i & 4 ) ? 1.f : 0;
+ cubePoint[2] = ( i & 4 ) ? 1.f : ( m_directX ? 0.f : -1.f ); // DirectX uses NDC z in [0,1]
- out[ i ] = ( invProj * cubePoint ).homogenized().xyz();
+ // this would be the hypercube ordering
+ // cubePoint[0] = ( i & 1 ) ? 1.f : -1.f;
+ // cubePoint[1] = ( i & 2 ) ? 1.f : -1.f;
+ // cubePoint[2] = ( i & 4 ) ? 1.f : ( m_directX ? 0.f : -1.f ); // DirectX uses NDC z in [0,1]
+
+ corners[ i ] = ( invViewProj * cubePoint ).homogenized().xyz();
}
- return out;
+ return corners;
+}
+
+std::vector< Plane3f > Camera::frustumPlanes() const
+{
+ auto corners = frustumCorners();
+ std::vector< Plane3f > planes( 6 );
+
+ // left
+ planes[ 0 ] = Plane3f( corners[ 0 ], corners[ 3 ], corners[ 4 ] );
+ // bottom
+ planes[ 1 ] = Plane3f( corners[ 1 ], corners[ 0 ], corners[ 4 ] );
+ // right
+ planes[ 2 ] = Plane3f( corners[ 2 ], corners[ 1 ], corners[ 5 ] );
+ // top
+ planes[ 3 ] = Plane3f( corners[ 3 ], corners[ 2 ], corners[ 6 ] );
+ // near
+ planes[ 4 ] = Plane3f( corners[ 0 ], corners[ 1 ], corners[ 2 ] );
+ // far
+ planes[ 5 ] = Plane3f( corners[ 5 ], corners[ 4 ], corners[ 6 ] );
+
+ return planes;
}
bool Camera::isZFarInfinite()
View
2 core/src/cameras/PerspectiveCamera.cpp
@@ -113,7 +113,7 @@ Matrix4f PerspectiveCamera::projectionMatrix() const
{
return Matrix4f::perspectiveProjection( m_left, m_right,
m_bottom, m_top,
- m_zNear, m_zFar, m_zFarIsInfinite );
+ m_zNear, m_zFar, m_directX );
}
}
View
65 core/src/geometry/FrustumUtils.cpp
@@ -0,0 +1,65 @@
+#include "geometry/FrustumUtils.h"
+
+// static
+FrustumUtils::IntersectionResult FrustumUtils::intersectBoundingBox( const BoundingBox3f& box, Plane3f planes[ 6 ] )
+{
+ auto boxCorners = box.corners();
+
+ // by default, we assume the box is completely inside
+ IntersectionResult result = INSIDE;
+
+ // and keep track, for each corner of the box
+ // how many vertices are inside vs outside
+ int nVerticesInside;
+ int nVerticesOutside;
+
+ // for each plane do ...
+ for( int i = 0; i < 6; ++i )
+ {
+ // reset counters for corners nVerticesInside and nVerticesOutside
+ nVerticesInside = 0;
+ nVerticesOutside = 0;
+
+ // for each corner of the box do ...
+ // get nVerticesOutside of the cycle as soon as a box as corners
+ // both inside and nVerticesOutside of the frustum
+ for( int k = 0; k < 8 && ( nVerticesInside == 0 || nVerticesOutside == 0 ); k++ )
+ {
+ // is the corner inside or outside?
+ float d = planes[ i ].distance( boxCorners[ k ] );
+ if( d < 0 )
+ {
+ ++nVerticesInside;
+ }
+ else
+ {
+ ++nVerticesOutside;
+ }
+ }
+
+ // if none of the box corners are on the inside halfspace
+ // then it's guaranteed to be outside, done
+ if( nVerticesInside == 0 )
+ {
+ return OUTSIDE;
+ }
+ // otherwise, at least some of them are inside
+ // but if some of them are *also* outside
+ // then we know for now that it intersects this plane
+ // (but it's not guaranteed to actually intersect the entire frustum)
+ else if( nVerticesOutside != 0 )
+ {
+ result = INTERESECTING;
+ }
+ // otherwise, we know that some vertices are inside
+ // and none are outside
+ // --> this box is completely inside (for this plane anyway)
+ else
+ {
+ assert( nVerticesInside == 8 );
+ assert( nVerticesOutside == 0 );
+ }
+ }
+
+ return result;
+}
View
0 core/src/geometry/Geometry.cpp
No changes.

0 comments on commit cb69335

Please sign in to comment.