Quantcast
Channel: Анал со зрелой
Viewing all articles
Browse latest Browse all 47

Compute Basis with SIMD

$
0
0

A while back Erin Catto made a cool post about his short function to compute a basis given a vector. The cool thing was that the basis is axis aligned if the input vector is axis aligned.

Catto noted that the function can be converted to branchless SIMD by using a select operation. So, a while ago I sat down and wrote the function, and only used it once. It didn’t really seem all too helpful to have a SIMD version, but it was fun to write anyway (I made use of Microsoft’s __Vectorcall):

//--------------------------------------------------------------------------------------------------
// http://box2d.org/2014/02/computing-a-basis/
inline mat3 __vectorcall Basis( __m128 a )
{
	// Suppose vector a has all equal components and is a unit vector: a = (s, s, s)
	// Then 3*s*s = 1, s = sqrt(1/3) = 0.57735027. This means that at least one component
	// of a unit vector must be greater or equal to 0.57735027.

	__m128 negA = Negate( a );
	__m128 t0 = Shuffle( a, negA, 3, 0, 1, 1 );
	__m128 b0 = Shuffle( t0, t0, 3, 3, 2, 0 );
	t0 = Shuffle( a, negA, 3, 1, 2, 2 );
	__m128 b1 = Shuffle( t0, t0, 3, 2, 1, 3 );

	__m128 absA = Abs( a );
	__m128 mask0 = { 0.57735027f, 0.57735027f, 0.57735027f, 0 };
	__m128 mask = _mm_cmpge_ps( mask0, absA );
	mask = Shuffle( mask, mask, 0, 0, 0, 0 );
	__m128 b = Select( b0, b1, mask );
	b = Normalize( b );
	__m128 c = Cross( a, b );

	return Rows( a, b, c );
}

 

TwitterRedditFacebookShare


Viewing all articles
Browse latest Browse all 47

Trending Articles