protected virtual void UpdateVertexData()
{
if ( _recalculateVertexData )
{
// Note: Even though we could be dealing with general a projection matrix here,
// it is incompatible with the infinite far plane, thus, we need to work
// with projection parameters.
// Calc near plane corners
Real nearLeft, nearRight, nearBottom, nearTop;
CalculateProjectionParameters( out nearLeft, out nearRight, out nearBottom, out nearTop );
// Treat infinite fardist as some arbitrary far value
Real farDist = ( _farDistance == 0 ) ? 100000 : _farDistance;
// Calc far palne corners
Real ratio = _projectionType == Projection.Perspective ? _farDistance / _nearDistance : 1;
Real farLeft = nearLeft * ratio;
Real farRight = nearRight * ratio;
Real farBottom = nearBottom * ratio;
Real farTop = nearTop * ratio;
// Calculate vertex positions
// 0 is the origin
// 1, 2, 3, 4 are the points on the near plane, top left first, clockwise
// 5, 6, 7, 8 are the points on the far plane, top left first, clockwise
HardwareVertexBuffer buffer = _vertexData.vertexBufferBinding.GetBuffer( 0 );
IntPtr posPtr = buffer.Lock( BufferLocking.Discard );
unsafe
{
float* pPos = (float*)posPtr.ToPointer();
// near plane (remember frustum is going in -Z direction)
*pPos++ = nearLeft;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = nearRight;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = nearRight;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = nearRight;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = nearRight;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = nearLeft;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = nearLeft;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = nearLeft;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
// far plane (remember frustum is going in -Z direction)
*pPos++ = farLeft;
*pPos++ = farTop;
*pPos++ = -farDist;
*pPos++ = farRight;
*pPos++ = farTop;
*pPos++ = -farDist;
*pPos++ = farRight;
*pPos++ = farTop;
*pPos++ = -farDist;
*pPos++ = farRight;
*pPos++ = farBottom;
*pPos++ = -farDist;
*pPos++ = farRight;
*pPos++ = farBottom;
*pPos++ = -farDist;
*pPos++ = farLeft;
*pPos++ = farBottom;
*pPos++ = -farDist;
*pPos++ = farLeft;
*pPos++ = farBottom;
*pPos++ = -farDist;
*pPos++ = farLeft;
*pPos++ = farTop;
*pPos++ = -farDist;
// Sides of the pyramid
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = nearLeft;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = nearRight;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = nearRight;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = 0.0f;
*pPos++ = nearLeft;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
// Sides of the box
*pPos++ = nearLeft;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = farLeft;
*pPos++ = farTop;
*pPos++ = -farDist;
*pPos++ = nearRight;
*pPos++ = nearTop;
*pPos++ = -_nearDistance;
*pPos++ = farRight;
*pPos++ = farTop;
*pPos++ = -farDist;
*pPos++ = nearRight;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = farRight;
*pPos++ = farBottom;
*pPos++ = -farDist;
*pPos++ = nearLeft;
*pPos++ = nearBottom;
*pPos++ = -_nearDistance;
*pPos++ = farLeft;
*pPos++ = farBottom;
*pPos++ = -farDist;
}
// don't forget to unlock!
buffer.Unlock();
_recalculateVertexData = false;
}
}