Frustum sphere

Started by
0 comments, last by Alundra 9 years, 8 months ago

Hi all,

Here my code to compute a bounding sphere from camera + near + far :


void ExtractFrustumSphere( CCameraActor* Camera, const float Near, const float Far, CVector3* Center, float* Radius )
{
  // Get the camera component.
  CCameraComponent* CameraComponent = static_cast< CCameraComponent* >( Camera->GetComponent( 0 ) );
 
  // Camera params.
  const CVector3 CameraPos = Camera->GetWorldTranslationVector();
  const CVector3 CameraRight = Camera->GetRightVector();
  const CVector3 CameraForward = Camera->GetForwardVector();
  const CVector3 CameraUp = Camera->GetUpVector();
 
  // Tangent values.
  const float TanFOVX = CMath::Tan( CameraComponent->GetAspectRatio() * CameraComponent->GetFieldOfView() * 0.5f );
  const float TanFOVY = CMath::Tan( CameraComponent->GetAspectRatio() );
  
  // Compute the half distance.
  const float HalfDistance = 0.5f * ( Far - Near );
  
  // Compute the center.
  *Center = CameraPos + CameraForward * ( Near + HalfDistance );
  
  // Compute the radius.
  *Radius = ( ( CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * HalfDistance ).Length();
}

I'm not sure if I use the correct way to compute the radius.

I think this is wrong because for a near of 0.1f and a far of 100.0f with a FOV of QUATER_PI, I have 246 of radius.

What is wrong in the calcule of the radius ?

Thanks for the help.

EDIT :

I saw I used a bad value for TanFOVY, I have changed to use :


const float TanFOVX = CMath::Tan( CameraComponent->GetAspectRatio() * CameraComponent->GetFieldOfView() * 0.5f );
const float TanFOVY = CMath::Tan( CameraComponent->GetFieldOfView() * 0.5f );

I Have a radius of 68 for the same values I said before, Is it the correct answer ?

Advertisement

Based on this image :

http://4.bp.blogspot.com/_tpaCGcSxgmE/TNut_PCw-EI/AAAAAAAAAQo/DbX2-k5lxao/s1600/trap_circum_circle.gif

The calcul gives a better result because no wasted space :


// Camera params.
const DE::CVector3 CameraRight = Camera->GetRightVector();
const DE::CVector3 CameraUp = Camera->GetUpVector();

// Tangent values.
const float TanFOVX = DE::CMath::Tan( 0.5f * CameraComponent->GetFieldOfView() * CameraComponent->GetAspectRatio() );
const float TanFOVY = DE::CMath::Tan( 0.5f * CameraComponent->GetFieldOfView() );

// Compute short parallel side.
const CVector3 NearPointA = ( -CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * Near;
const CVector3 NearPointB = ( +CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * Near;
const float a = ( NearPointB - NearPointA ).Length();

// Compute the long parallel side.
const CVector3 FarPointA = ( -CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * Far;
const CVector3 FarPointB = ( +CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * Far;
const float b = ( FarPointB - FarPointA ).Length();

// Compute the bounding sphere.
const float h = Far - Near;
const float Offset = 0.5f * (h + (a - b) * (a + b) / (4.0f * h));
BSphere->m_Center = CameraPos + CameraForward * ( Far - Offset );
BSphere->m_Radius = CMath::Sqrt( CMath::Sqr( 0.5f * b ) + CMath::Sqr( Offset ) );

The problem is that works fine if you look the top-view and the side-view but if you look the front view you see a problem :

http://uppix.com/f-Screenshot_2014_53e78ea8001738a7.png

The camera is ortho to see the problem.

The top-view and the side-view :

http://uppix.com/f-Screenshot_2014_53e6c8ff001737b1.png

http://uppix.com/f-Screenshot_2014_53e6d05c001737c2.png

The problem is the calcule is in 2D and must be changed to take account of the 3D because a frustum has upper and bottom side.

Hope you can help on this one, surely the solution is not far.

Thanks

This topic is closed to new replies.

Advertisement