public void OrthoNormalize()
{
// Normalize first
Normalize();
// Find the most minimal divergence in the existing 3 axes
float fDivergenceXY = System.Math.Abs( GetRow0() | GetRow1() );
float fDivergenceYZ = System.Math.Abs( GetRow1() | GetRow2() );
float fDivergenceZX = System.Math.Abs( GetRow2() | GetRow0() );
int MinDivergenceRowIndex = 0;
if ( fDivergenceXY < fDivergenceYZ )
{
if ( fDivergenceXY < fDivergenceZX )
MinDivergenceRowIndex = 2;
else
MinDivergenceRowIndex = 1;
}
else
{
if ( fDivergenceYZ < fDivergenceZX )
MinDivergenceRowIndex = 0;
else
MinDivergenceRowIndex = 1;
}
// The complementary axis is the safest to be recomputed
SetRow( MinDivergenceRowIndex, ((float3) GetRow( ms_RotIndex[MinDivergenceRowIndex+1] ) ^ (float3) GetRow( ms_RotIndex[MinDivergenceRowIndex+2] )).Normalize(), 0.0f );
// Find the minimal divergence in the remaining 2 axes
float fDivergence0 = System.Math.Abs( GetRow( ms_RotIndex[MinDivergenceRowIndex+0] ) | GetRow( ms_RotIndex[MinDivergenceRowIndex+1] ) );
float fDivergence1 = System.Math.Abs( GetRow( ms_RotIndex[MinDivergenceRowIndex+0] ) | GetRow( ms_RotIndex[MinDivergenceRowIndex+2] ) );
int MinSecondDivergenceRowIndex = 0;
if ( fDivergence0 < fDivergence1 )
MinSecondDivergenceRowIndex = ms_RotIndex[MinDivergenceRowIndex + 2];
else
MinSecondDivergenceRowIndex = ms_RotIndex[MinDivergenceRowIndex + 1];
// The complementary axis is the safest to be recomputed
SetRow( MinSecondDivergenceRowIndex, ((float3) GetRow( ms_RotIndex[MinSecondDivergenceRowIndex+1] ) ^ (float3) GetRow( ms_RotIndex[MinSecondDivergenceRowIndex+2] )).Normalize(), 0.0f );
// Compute the final, remaining axis
int MinDivergenceIndex = System.Math.Min( MinDivergenceRowIndex, MinSecondDivergenceRowIndex );
int MaxDivergenceIndex = System.Math.Max( MinDivergenceRowIndex, MinSecondDivergenceRowIndex );
int RemainingAxisIndex = MinDivergenceIndex == 1 ? 0 : (MaxDivergenceIndex == 1 ? 2 : 1);
SetRow( RemainingAxisIndex, (float3) GetRow( MinDivergenceRowIndex ) ^ (float3) GetRow( MinSecondDivergenceRowIndex ), 0.0f );
}