mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-22 08:03:45 +00:00
SceneCullingState with culling and camera frustum
- Fix for issue https://github.com/GarageGames/Torque3D/issues/525 This fix takes into account the skewed view into the world when you have a projection offset and the ability to see further into the scene at the edges opposite to the offset. - SceneCullingState now has two frustum rather than one: a culling frustum and camera frustum. - The camera frustum should be referenced when you need the projection matrix or don't want a skewed frustum. - The culling frustum should be referenced during any scene culling or when determining what dynamic geometry to render. It currently skews itself to take into account any projection offset (automatically calculated in SceneCullingState constructor). - When there is no projection offset, the camera frustum and culling frustum are the same. This usually means any time when not using the Oculus Rift.
This commit is contained in:
parent
9af13248cf
commit
91e542b8ec
22 changed files with 161 additions and 47 deletions
|
|
@ -228,6 +228,100 @@ void Frustum::cropNearFar(F32 newNearDist, F32 newFarDist)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool Frustum::bakeProjectionOffset()
|
||||
{
|
||||
// Nothing to bake if ortho
|
||||
if( mIsOrtho )
|
||||
return false;
|
||||
|
||||
// Nothing to bake if no offset
|
||||
if( mProjectionOffset.isZero() )
|
||||
return false;
|
||||
|
||||
// Near plane points in camera space
|
||||
Point3F np[4];
|
||||
np[0].set( mNearLeft, mNearDist, mNearTop ); // NearTopLeft
|
||||
np[1].set( mNearRight, mNearDist, mNearTop ); // NearTopRight
|
||||
np[2].set( mNearLeft, mNearDist, mNearBottom ); // NearBottomLeft
|
||||
np[3].set( mNearRight, mNearDist, mNearBottom ); // NearBottomRight
|
||||
|
||||
// Generate the near plane
|
||||
PlaneF nearPlane( np[0], np[1], np[3] );
|
||||
|
||||
// Far plane points in camera space
|
||||
const F32 farOverNear = mFarDist / mNearDist;
|
||||
Point3F fp0( mNearLeft * farOverNear, mFarDist, mNearTop * farOverNear ); // FarTopLeft
|
||||
Point3F fp1( mNearRight * farOverNear, mFarDist, mNearTop * farOverNear ); // FarTopRight
|
||||
Point3F fp2( mNearLeft * farOverNear, mFarDist, mNearBottom * farOverNear ); // FarBottomLeft
|
||||
Point3F fp3( mNearRight * farOverNear, mFarDist, mNearBottom * farOverNear ); // FarBottomRight
|
||||
|
||||
// Generate the far plane
|
||||
PlaneF farPlane( fp0, fp1, fp3 );
|
||||
|
||||
// The offset camera point
|
||||
Point3F offsetCamera( mProjectionOffset.x, 0.0f, mProjectionOffset.y );
|
||||
|
||||
// The near plane point we'll be using for our calculations below
|
||||
U32 nIndex = 0;
|
||||
if( mProjectionOffset.x < 0.0 )
|
||||
{
|
||||
// Offset to the left so we'll need to use the near plane point on the right
|
||||
nIndex = 1;
|
||||
}
|
||||
if( mProjectionOffset.y > 0.0 )
|
||||
{
|
||||
// Offset to the top so we'll need to use the near plane point at the bottom
|
||||
nIndex += 2;
|
||||
}
|
||||
|
||||
// Begin by calculating the offset point on the far plane as it goes
|
||||
// from the offset camera to the edge of the near plane.
|
||||
Point3F farPoint;
|
||||
Point3F fdir = np[nIndex] - offsetCamera;
|
||||
fdir.normalize();
|
||||
if( farPlane.intersect(offsetCamera, fdir, &farPoint) )
|
||||
{
|
||||
// Calculate the new near plane edge from the non-offset camera position
|
||||
// to the far plane point from above.
|
||||
Point3F nearPoint;
|
||||
Point3F ndir = farPoint;
|
||||
ndir.normalize();
|
||||
if( nearPlane.intersect( Point3F::Zero, ndir, &nearPoint) )
|
||||
{
|
||||
// Handle a x offset
|
||||
if( mProjectionOffset.x < 0.0 )
|
||||
{
|
||||
// The new near plane right side
|
||||
mNearRight = nearPoint.x;
|
||||
}
|
||||
else if( mProjectionOffset.x > 0.0 )
|
||||
{
|
||||
// The new near plane left side
|
||||
mNearLeft = nearPoint.x;
|
||||
}
|
||||
|
||||
// Handle a y offset
|
||||
if( mProjectionOffset.y < 0.0 )
|
||||
{
|
||||
// The new near plane top side
|
||||
mNearTop = nearPoint.y;
|
||||
}
|
||||
else if( mProjectionOffset.y > 0.0 )
|
||||
{
|
||||
// The new near plane bottom side
|
||||
mNearBottom = nearPoint.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mDirty = true;
|
||||
|
||||
// Indicate that we've modified the frustum
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FrustumData::_update() const
|
||||
{
|
||||
if( !mDirty )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue