[util] Add qconj, vtrunc, vceil and vfloor functions

I had forgotten these rather critical functions. Both double and float
versions are included.
This commit is contained in:
Bill Currie 2020-12-28 14:52:36 +09:00
parent 03fcb530c7
commit 1ddd57b09e
3 changed files with 106 additions and 0 deletions

View file

@ -133,6 +133,14 @@ qrotd (vec4d_t a, vec4d_t b)
return q; return q;
} }
vec4d_t qconjd (vec4d_t q) __attribute__((const));
vec4d_t
qconjd (vec4d_t q)
{
const vec4l_t neg = { 1lu << 63, 1lu << 63, 1lu << 63, 0 };
return _mm256_xor_pd (q, (__m256d) neg);
}
vec4d_t loadvec3d (const double v3[]) __attribute__((pure, access(read_only, 1))); vec4d_t loadvec3d (const double v3[]) __attribute__((pure, access(read_only, 1)));
vec4d_t vec4d_t
loadvec3d (const double v3[]) loadvec3d (const double v3[])
@ -153,4 +161,22 @@ void storevec3d (double v3[3], vec4d_t v4)
v3[2] = v4[2]; v3[2] = v4[2];
} }
vec4d_t vceild (vec4d_t v) __attribute__((const));
vec4d_t vceild (vec4d_t v)
{
return _mm256_ceil_pd (v);
}
vec4d_t vfloord (vec4d_t v) __attribute__((const));
vec4d_t vfloord (vec4d_t v)
{
return _mm256_floor_pd (v);
}
vec4d_t vtruncd (vec4d_t v) __attribute__((const));
vec4d_t vtruncd (vec4d_t v)
{
return _mm256_round_pd (v, _MM_FROUND_TRUNC);
}
#endif//__QF_simd_vec4d_h #endif//__QF_simd_vec4d_h

View file

@ -127,6 +127,18 @@ qrotf (vec4f_t a, vec4f_t b)
return q; return q;
} }
/** Return the conjugate of the quaternion.
*
* That is, [-x, -y, -z, w].
*/
vec4f_t qconjf (vec4f_t q) __attribute__((const));
vec4f_t
qconjf (vec4f_t q)
{
const vec4i_t neg = { 1u << 31, 1u << 31, 1u << 31, 0 };
return _mm_xor_ps (q, (__m128) neg);
}
vec4f_t loadvec3f (const float v3[3]) __attribute__((pure, access(read_only, 1))); vec4f_t loadvec3f (const float v3[3]) __attribute__((pure, access(read_only, 1)));
vec4f_t vec4f_t
loadvec3f (const float v3[3]) loadvec3f (const float v3[3])
@ -156,4 +168,22 @@ void storevec3f (float v3[3], vec4f_t v4)
v3[2] = v4[2]; v3[2] = v4[2];
} }
vec4f_t vceilf (vec4f_t v) __attribute__((const));
vec4f_t vceilf (vec4f_t v)
{
return _mm_ceil_ps (v);
}
vec4f_t vfloorf (vec4f_t v) __attribute__((const));
vec4f_t vfloorf (vec4f_t v)
{
return _mm_floor_ps (v);
}
vec4f_t vtruncf (vec4f_t v) __attribute__((const));
vec4f_t vtruncf (vec4f_t v)
{
return _mm_round_ps (v, _MM_FROUND_TRUNC);
}
#endif//__QF_simd_vec4f_h #endif//__QF_simd_vec4f_h

View file

@ -39,6 +39,46 @@ typedef struct {
vec4f_t ulp_errors; vec4f_t ulp_errors;
} vec4f_test_t; } vec4f_test_t;
static vec4d_t tvtruncd (vec4d_t v, vec4d_t ignore)
{
return vtruncd (v);
}
static vec4d_t tvceild (vec4d_t v, vec4d_t ignore)
{
return vceild (v);
}
static vec4d_t tvfloord (vec4d_t v, vec4d_t ignore)
{
return vfloord (v);
}
static vec4d_t tqconjd (vec4d_t v, vec4d_t ignore)
{
return qconjd (v);
}
static vec4f_t tvtruncf (vec4f_t v, vec4f_t ignore)
{
return vtruncf (v);
}
static vec4f_t tvceilf (vec4f_t v, vec4f_t ignore)
{
return vceilf (v);
}
static vec4f_t tvfloorf (vec4f_t v, vec4f_t ignore)
{
return vfloorf (v);
}
static vec4f_t tqconjf (vec4f_t v, vec4f_t ignore)
{
return qconjf (v);
}
static vec4d_test_t vec4d_tests[] = { static vec4d_test_t vec4d_tests[] = {
// 3D dot products // 3D dot products
{ dotd, right, right, one }, { dotd, right, right, one },
@ -140,6 +180,11 @@ static vec4d_test_t vec4d_tests[] = {
{ qrotd, up, forward, { -s05, 0, 0, s05 }, { qrotd, up, forward, { -s05, 0, 0, s05 },
{ 1.1e-16, 0, 0, 0} }, { 1.1e-16, 0, 0, 0} },
{ qrotd, up, up, qident }, { qrotd, up, up, qident },
{ tvtruncd, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -1, -2 } },
{ tvceild, { 1.1, 2.9, -1.1, -2.9 }, {}, { 2, 3, -1, -2 } },
{ tvfloord, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -2, -3 } },
{ tqconjd, one, {}, { -1, -1, -1, 1 } },
}; };
#define num_vec4d_tests (sizeof (vec4d_tests) / (sizeof (vec4d_tests[0]))) #define num_vec4d_tests (sizeof (vec4d_tests) / (sizeof (vec4d_tests[0])))
@ -226,6 +271,11 @@ static vec4f_test_t vec4f_tests[] = {
{ qrotf, up, right, { 0, s05, 0, s05 } }, { qrotf, up, right, { 0, s05, 0, s05 } },
{ qrotf, up, forward, { -s05, 0, 0, s05 } }, { qrotf, up, forward, { -s05, 0, 0, s05 } },
{ qrotf, up, up, qident }, { qrotf, up, up, qident },
{ tvtruncf, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -1, -2 } },
{ tvceilf, { 1.1, 2.9, -1.1, -2.9 }, {}, { 2, 3, -1, -2 } },
{ tvfloorf, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -2, -3 } },
{ tqconjf, one, {}, { -1, -1, -1, 1 } },
}; };
#define num_vec4f_tests (sizeof (vec4f_tests) / (sizeof (vec4f_tests[0]))) #define num_vec4f_tests (sizeof (vec4f_tests) / (sizeof (vec4f_tests[0])))