Example #1
0
/// update all internal data
//////////////////////////////////////////////////////////////////////////
bool CScaler::UpdateInternalsAndGetVisibility()
{
	VisRenderContext_cl* pCtx = Vision::Contexts.GetCurrentContext();
	const VisMatrix4x4_cl& mtxProjection = pCtx->GetProjectionMatrix();
	VisContextCamera_cl* pContextCam = pCtx->GetCamera();
	pContextCam->GetWorldMatrix( m_mtxViewProjection ); // it`s View mtx and not all cells are filled?!?, fix below

	// ogl View to dx View mtx crap
	float* pGlmatrix = m_mtxViewProjection.GetFloatPtr();
	pGlmatrix[ 2 ]  = -pGlmatrix[ 2 ];
	pGlmatrix[ 6 ]  = -pGlmatrix[ 6 ];
	pGlmatrix[ 10 ] = -pGlmatrix[ 10 ];
	pGlmatrix[ 14 ] = -pGlmatrix[ 14 ];
	pGlmatrix[ 15 ] = 1.f; //this must be here, GetWorldMatrix DOES NOT fill all cells !!!

	// multiply is now DX style  (ogl is projection*view*world)
	m_mtxViewProjection *= mtxProjection;

	// get transpose mtx of ViewProjection
	m_mtxViewProjectionT = m_mtxViewProjection;
	m_mtxViewProjectionT.Transpose();

	// gen VPInverse mtx (if sended to shader, must be transposed)
	m_mtxViewProjectionInv = m_mtxViewProjection;
	m_mtxViewProjectionInv.InvertEx();

	// calculate -far & far plane vectors (homogeneous space)
	m_NearPlane.v1.SetXYZW( -1, 1, 0, 1 );
	m_NearPlane.v2.SetXYZW( 1, 1, 0, 1 );
	m_NearPlane.v3.SetXYZW( 1, -1, 0, 1 );
	m_NearPlane.v4.SetXYZW( -1, -1, 0, 1 );

	m_FarPlane.v1.SetXYZW( -1, 1, 1, 1 );
	m_FarPlane.v2.SetXYZW( 1, 1, 1, 1 );
	m_FarPlane.v3.SetXYZW( 1, -1, 1, 1 );
	m_FarPlane.v4.SetXYZW( -1, -1, 1, 1 );

	// w are all ones so Vision may be used
	m_NearPlane.v1 *= m_mtxViewProjectionInv;
	m_NearPlane.v2 *= m_mtxViewProjectionInv;
	m_NearPlane.v3 *= m_mtxViewProjectionInv;
	m_NearPlane.v4 *= m_mtxViewProjectionInv;

	m_FarPlane.v1 *= m_mtxViewProjectionInv;
	m_FarPlane.v2 *= m_mtxViewProjectionInv;
	m_FarPlane.v3 *= m_mtxViewProjectionInv;
	m_FarPlane.v4 *= m_mtxViewProjectionInv;

	_GetWorldPos( m_NearPlane, m_WorldNearPlane );
	_GetWorldPos( m_FarPlane, m_WorldFarPlane );

	GetIntersectionsAndPointsBeetween(); // will fill m_aIntesections & counter

	// skip if can`t generate proper matrix ( volume is outside of frustum )
	if( m_iInterectionsCount >= 4 ) // valid
	{
		// get clip space coords to calculate XY span
		for( int i=0; i<m_iInterectionsCount; i++ )
		{
			//m_aIntersections[ i ].w = 1.f; // Vision use w as 1 so don`t set
			m_aIntersections[ i ].z = 0.f; // TODO: should be water level
			m_aIntersections[ i ] *= m_mtxViewProjectionT; // use transposed mtx
			m_aIntersections[ i ].x /= m_aIntersections[ i ].w;
			m_aIntersections[ i ].y /= m_aIntersections[ i ].w;
			//m_aIntersections[ i ].z /= m_aIntersections[ i ].w; // we dont need Z
		}

		float fXMin = FLT_MAX; float fXMax = -FLT_MAX;
		float fYMin = FLT_MAX; float fYMax = -FLT_MAX;

		for( int i=0; i<m_iInterectionsCount; i++ )
		{
			if( m_aIntersections[ i ].x > fXMax )
				fXMax = m_aIntersections[ i ].x;
			if ( m_aIntersections[ i ].x < fXMin )
				fXMin = m_aIntersections[ i ].x;
			if( m_aIntersections[ i ].y > fYMax )
				fYMax = m_aIntersections[ i ].y;
			if ( m_aIntersections[ i ].y < fYMin )
				fYMin = m_aIntersections[ i ].y;
		}

		// build scaling matrix. it prevents h-space verts in shader to run out of range

		/* normal way
		VisMatrix4x4_cl mtxScale;
		mtxScale.Identity();
		mtxScale[ 0 ] = fXMax - fXMin;
		mtxScale[ 5 ] = fYMax - fYMin;
		mtxScale[ 12 ] = fXMin;
		mtxScale[ 13 ] = fYMin;
		mtxScale.Transpose();
		*/

		// faster way
		m_mtxScale[ 0 ] = fXMax - fXMin;
		m_mtxScale[ 5 ] = fYMax - fYMin;
		m_mtxScale[ 3 ] = fXMin;
		m_mtxScale[ 7 ] = fYMin;


		m_mtxViewProjectionInv *= m_mtxScale;

		m_NearPlane.v1.SetXYZW( 0, 1, 0, 1 );
		m_NearPlane.v2.SetXYZW( 1, 1, 0, 1 );
		m_NearPlane.v3.SetXYZW( 1, 0, 0, 1 );
		m_NearPlane.v4.SetXYZW( 0, 0, 0, 1 );

		m_FarPlane.v1.SetXYZW( 0, 1, 1, 1 );
		m_FarPlane.v2.SetXYZW( 1, 1, 1, 1 );
		m_FarPlane.v3.SetXYZW( 1, 0, 1, 1 );
		m_FarPlane.v4.SetXYZW( 0, 0, 1, 1 );

		m_NearPlane.v1 *= m_mtxViewProjectionInv;
		m_NearPlane.v2 *= m_mtxViewProjectionInv;
		m_NearPlane.v3 *= m_mtxViewProjectionInv;
		m_NearPlane.v4 *= m_mtxViewProjectionInv;

		m_FarPlane.v1 *= m_mtxViewProjectionInv;
		m_FarPlane.v2 *= m_mtxViewProjectionInv;
		m_FarPlane.v3 *= m_mtxViewProjectionInv;
		m_FarPlane.v4 *= m_mtxViewProjectionInv;
		return true;
	}else
	{
		// do not render
		return false;
	}
}