void Frustum<NumericT>::build_frustrum_from_matrix (const Matrix<4, 4, NumericT> & m) { // The constructor used for Plane will normalize its elements automatically // Left (m3 + m0) _planes[LEFT] = convert_plane_from_matrix_eqn(m.at(3, 0)+m.at(0, 0), m.at(3, 1)+m.at(0, 1), m.at(3, 2)+m.at(0, 2), (m.at(3, 3)+m.at(0, 3))); // Right (m3 - m0) _planes[RIGHT] = convert_plane_from_matrix_eqn(m.at(3, 0)-m.at(0, 0), m.at(3, 1)-m.at(0, 1), m.at(3, 2)-m.at(0, 2), (m.at(3, 3)-m.at(0, 3))); // Top (m3 - m1) _planes[TOP] = convert_plane_from_matrix_eqn(m.at(3, 0)-m.at(1, 0), m.at(3, 1)-m.at(1, 1), m.at(3, 2)-m.at(1, 2), (m.at(3, 3)-m.at(1, 3))); // Bottom (m3 + m1) _planes[BOTTOM] = convert_plane_from_matrix_eqn(m.at(3, 0)+m.at(1, 0), m.at(3, 1)+m.at(1, 1), m.at(3, 2)+m.at(1, 2), (m.at(3, 3)+m.at(1, 3))); // Near _planes[NEAR] = convert_plane_from_matrix_eqn(m.at(2, 0), m.at(2, 1), m.at(2, 2), m.at(2, 3)); // Far (m3 - m2) _planes[FAR] = convert_plane_from_matrix_eqn(m.at(3, 0)-m.at(2, 0), m.at(3, 1)-m.at(2, 1), m.at(3, 2)-m.at(2, 2), (m.at(3, 3)-m.at(2, 3))); // Calculate object-space points for box coordinates: AlignedBox<3, NumericT> clip_box(-1, 1); Vec3u k(2); auto inverse_view_matrix = inverse(m); for (std::size_t i = 0; i < 8; i += 1) { _corners[i] = inverse_view_matrix * clip_box.corner(k.distribute(i)); } _near_center = inverse_view_matrix * Vec3T(0, 0, 1); _far_center = inverse_view_matrix * Vec3T(0, 0, -1); }
bool FrustumT<T>::contains( const AxisAlignedBox &box ) const { for( size_t i = 0; i < 6; ++i ) { if( mFrustumPlanes[i].distance( Vec3T( box.getPositive( vec3( mFrustumPlanes[i].getNormal() ) ) ) ) < 0 ) return false; else if( mFrustumPlanes[i].distance( Vec3T( box.getNegative( vec3( mFrustumPlanes[i].getNormal() ) ) ) ) < 0 ) return false; } return true; }
RectT<T> RectT<T>::transformed( const Mat3T& matrix ) const { Vec2T center = Vec2T( x1 + x2, y1 + y2 ) / (T) 2; Vec2T extents = glm::abs( Vec2T( x2, y2 ) - center ); Vec3T x = matrix * Vec3T( extents.x, 0, 0 ); Vec3T y = matrix * Vec3T( 0, extents.y, 0 ); extents = Vec2T( glm::abs( x ) + glm::abs( y ) ); center = Vec2T( matrix * Vec3T( center, 1 ) ); return RectT<T>( center.x - extents.x, center.y - extents.y, center.x + extents.x, center.y + extents.y ); }
void RectT<T>::transform( const Mat3T &matrix ) { Vec2T center = Vec2T( x1 + x2, y1 + y2 ) / (T) 2; Vec2T extents = glm::abs( Vec2T( x2, y2 ) - center ); Vec3T x = matrix * Vec3T( extents.x, 0, 0 ); Vec3T y = matrix * Vec3T( 0, extents.y, 0 ); extents = Vec2T( glm::abs( x ) + glm::abs( y ) ); center = Vec2T( matrix * Vec3T( center, 1 ) ); x1 = center.x - extents.x; y1 = center.y - extents.y; x2 = center.x + extents.x; y2 = center.y + extents.y; }
void FrustumT<T>::set( const Camera &cam, const Vec3T &ntl, const Vec3T &ntr, const Vec3T &nbl, const Vec3T &nbr ) { Vec3T eye = Vec3T( cam.getEyePoint() ); T farClip = cam.getFarClip(); Vec3T ftl = normalize( ntl - eye ) * farClip; Vec3T ftr = normalize( ntr - eye ) * farClip; Vec3T fbl = normalize( nbl - eye ) * farClip; Vec3T fbr = normalize( nbr - eye ) * farClip; set( ntl, ntr, nbl, nbr, ftl, ftr, fbl, fbr ); }
bool FrustumT<T>::intersects( const Sphere &sphere ) const { return intersects( Vec3T( sphere.getCenter() ), (T)sphere.getRadius() ); }
bool FrustumT<T>::contains( const Sphere &sphere ) const { return contains( Vec3T( sphere.getCenter() ), (T)sphere.getRadius() ); }