예제 #1
0
// static
BoundingBox3f BoundingBox3f::unite( const BoundingBox3f& b0, const BoundingBox3f& b1 )
{
    Vector3f b0Min = b0.minimum();
    Vector3f b0Max = b0.maximum();
    Vector3f b1Min = b1.minimum();
    Vector3f b1Max = b1.maximum();

    Vector3f newMin( min( b0Min.x, b1Min.x ), min( b0Min.y, b1Min.y ), min( b0Min.z, b1Min.z ) );
    Vector3f newMax( max( b0Max.x, b1Max.x ), max( b0Max.y, b1Max.y ), max( b0Max.z, b1Max.z ) );

    return BoundingBox3f( newMin, newMax );
}
예제 #2
0
// static
BoundingBox3f BoundingBox3f::intersect( const BoundingBox3f& b0, const BoundingBox3f& b1 )
{
    Vector3f b0Min = b0.minimum();
    Vector3f b0Max = b0.maximum();
    Vector3f b1Min = b1.minimum();
    Vector3f b1Max = b1.maximum();

    Vector3f newMin( max( b0Min.x, b1Min.x ), max( b0Min.y, b1Min.y ), max( b0Min.z, b1Min.z ) );
    Vector3f newMax( min( b0Max.x, b1Max.x ), min( b0Max.y, b1Max.y ), min( b0Max.z, b1Max.z ) );

    for(int i = 0; i < 3; ++i)
        newMax[i] = max(newMax[i], newMin[i]);

    return BoundingBox3f( newMin, newMax );
}
예제 #3
0
bool BoundingBox3f::overlaps( const BoundingBox3f& other )
{
	bool bOverlapsInDirection[3];

	Vector3f otherMin = other.minimum();
	Vector3f otherMax = other.maximum();

	for( int i = 0; i < 3; ++i )
	{
		bool bMinInside0 = ( otherMin[i] >= m_min[i] ) && ( otherMin[i] <= m_max[i] );
		bool bMinInside1 = ( m_min[i] >= otherMin[i] ) && ( m_min[i] <= otherMax[i] );

		bool bMaxInside0 = ( otherMax[i] >= m_min[i] ) && ( otherMax[i] <= m_max[i] );
		bool bMaxInside1 = ( m_max[i] >= otherMin[i] ) && ( m_max[i] <= otherMax[i] );

		bool bMinInside = bMinInside0 || bMinInside1;
		bool bMaxInside = bMaxInside0 || bMaxInside1;

		bOverlapsInDirection[i] = bMinInside || bMaxInside;
	}

	return bOverlapsInDirection[0] && bOverlapsInDirection[1] && bOverlapsInDirection[2];
}
예제 #4
0
// virtual
Matrix4f DirectionalLight::lightMatrix( const Camera& camera, const BoundingBox3f& sceneBoundingBox )
{
    const float feather = 1.01;

	Matrix3f lightLinear = lightBasis();
	Vector3f eye = camera.getEye();

	// get the corners of the view frustum in light coordinates
	// with the z = 0 plane at the eye
	QVector< Vector3f > frustumCorners = camera.getFrustumCorners();

    BoundingBox3f frustumBB;
    for( int i = 0; i < frustumCorners.size(); ++i )
        frustumBB.enlarge(frustumCorners[i]);

    BoundingBox3f sceneAndFrustum =  BoundingBox3f::intersect(frustumBB, sceneBoundingBox);

    QVector< Vector3f > sceneCorners = sceneBoundingBox.corners();
	QVector< Vector3f > sceneAndFrustumCorners = sceneAndFrustum.corners();

	for( int i = 0; i < sceneAndFrustumCorners.size(); ++i )
	{
        sceneAndFrustumCorners[ i ] = lightLinear * ( sceneAndFrustumCorners[ i ] - eye );
        sceneCorners[ i ] = lightLinear * ( sceneCorners[ i ] - eye );
	}

    BoundingBox3f inLightCoordinates;
    for(int i = 0; i < sceneAndFrustumCorners.size(); ++i)
        inLightCoordinates.enlarge(sceneAndFrustumCorners[i]);

    Vector3f maxCorner = inLightCoordinates.maximum();
    Vector3f minCorner = inLightCoordinates.minimum();

    Vector3f center = inLightCoordinates.center();
    maxCorner = center + feather * (maxCorner - center);
    minCorner = center + feather * (minCorner - center);

	// add eye point
	for(int j = 0; j < 3; ++j)
	{
		maxCorner[j] = qMax( maxCorner[ j ], 0.0f );
		minCorner[j] = qMin( minCorner[ j ], 0.0f );
	}

	// bound the near plane to the scene
	for( int i = 0; i < sceneCorners.size(); ++i )
	{
		minCorner[2] = qMin( minCorner[2], sceneCorners[ i ][ 2 ] );
	}

	// finally, compute the full light matrix
	Matrix4f lightMatrix;
	lightMatrix.setSubmatrix3x3( 0, 0, lightLinear );
	Vector3f origin = 0.5 * ( minCorner + maxCorner );
	origin[2] = minCorner[2];
	lightMatrix.setCol( 3, Vector4f( -origin, 1.f ) - Vector4f( lightLinear * eye, 0.f ) );
	for(int i = 0; i < 3; ++i)
	{
		lightMatrix.setRow( i, lightMatrix.getRow( i ) * ( ( i == 2 ) ? 1.f : 2.f ) / ( maxCorner[i] - minCorner[i] ) );
	}

	return lightMatrix;
}