parent
f6ad306a57
commit
cb14815832
@ -0,0 +1,57 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2014, Jan BOON
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NLMISC_VECTORF_H
|
||||
#define NLMISC_VECTORF_H
|
||||
#include "types_nl.h"
|
||||
|
||||
// System includes
|
||||
#ifdef NL_HAS_SSE2
|
||||
# include <xmmintrin.h>
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
// STL includes
|
||||
|
||||
// NLMISC includes
|
||||
#include "vectorf_types.h"
|
||||
#include "vectorf_misc.h"
|
||||
#include "vectorf_swizzle.h"
|
||||
#include "vectorf_accessors.h"
|
||||
#include "vectorf_math.h"
|
||||
#include "vectorf_operators.h"
|
||||
|
||||
// Project includes
|
||||
|
||||
namespace NLMISC {
|
||||
|
||||
} /* namespace NLMISC */
|
||||
|
||||
#endif /* #ifndef NLMISC_VECTORF_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,694 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2014, Jan BOON
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NLMISC_VECTORF_ACCESSORS_H
|
||||
#define NLMISC_VECTORF_ACCESSORS_H
|
||||
#include "types_nl.h"
|
||||
|
||||
// System includes
|
||||
#ifdef NL_HAS_SSE2
|
||||
# include <xmmintrin.h>
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
// STL includes
|
||||
|
||||
// NLMISC includes
|
||||
|
||||
// Project includes
|
||||
|
||||
namespace NLMISC {
|
||||
|
||||
NL_FORCE_INLINE float getX(const CVector1F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return _mm_cvtss_f32(v.mm);
|
||||
#else
|
||||
return v.x;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getX(const CVector2F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return _mm_cvtss_f32(v.mm);
|
||||
#else
|
||||
return v.x;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getY(const CVector2F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F g;
|
||||
g.mm = _mm_shuffle_ps(v.mm, v.mm, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
return _mm_cvtss_f32(g.mm);
|
||||
#else
|
||||
return v.y;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getX(const CVector3F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return _mm_cvtss_f32(v.mm);
|
||||
#else
|
||||
return v.x;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getY(const CVector3F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F g;
|
||||
g.mm = _mm_shuffle_ps(v.mm, v.mm, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
return _mm_cvtss_f32(g.mm);
|
||||
#else
|
||||
return v.y;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getZ(const CVector3F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F g;
|
||||
g.mm = _mm_shuffle_ps(v.mm, v.mm, _MM_SHUFFLE(2, 2, 2, 2));
|
||||
return _mm_cvtss_f32(g.mm);
|
||||
#else
|
||||
return v.z;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getX(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return _mm_cvtss_f32(v.mm);
|
||||
#else
|
||||
return v.x;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getY(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F g;
|
||||
g.mm = _mm_shuffle_ps(v.mm, v.mm, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
return _mm_cvtss_f32(g.mm);
|
||||
#else
|
||||
return v.y;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getZ(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F g;
|
||||
g.mm = _mm_shuffle_ps(v.mm, v.mm, _MM_SHUFFLE(2, 2, 2, 2));
|
||||
return _mm_cvtss_f32(g.mm);
|
||||
#else
|
||||
return v.z;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE float getW(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F g;
|
||||
g.mm = _mm_shuffle_ps(v.mm, v.mm, _MM_SHUFFLE(3, 3, 3, 3));
|
||||
return _mm_cvtss_f32(g.mm);
|
||||
#else
|
||||
return v.w;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F setX(const CVector2F &src, const float x)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F v1x;
|
||||
v1x.mm = _mm_set_ss(x);
|
||||
CVector2F result;
|
||||
result.mm = _mm_move_ss(src.mm, v1x.mm);
|
||||
return result;
|
||||
#else
|
||||
CVector2F result = src;
|
||||
result.x = x;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F setX(const CVector3F &src, const float x)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F v1x;
|
||||
v1x.mm = _mm_set_ss(x);
|
||||
CVector3F result;
|
||||
result.mm = _mm_move_ss(src.mm, v1x.mm);
|
||||
return result;
|
||||
#else
|
||||
CVector3F result = src;
|
||||
result.x = x;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F setX(const CVector4F &src, const float x)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F v1x;
|
||||
v1x.mm = _mm_set_ss(x);
|
||||
CVector4F result;
|
||||
result.mm = _mm_move_ss(src.mm, v1x.mm);
|
||||
return result;
|
||||
#else
|
||||
CVector4F result = src;
|
||||
result.x = x;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector2F setY(const CVector2F &src, const float y)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return yx(setX(yx(src), y));
|
||||
#else
|
||||
CVector2F result = src;
|
||||
result.y = y;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F setY(const CVector3F &src, const float y)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return yxz(setX(yxz(src), y));
|
||||
#else
|
||||
CVector3F result = src;
|
||||
result.y = y;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F setY(const CVector4F &src, const float y)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return yxzw(setX(yxzw(src), y));
|
||||
#else
|
||||
CVector4F result = src;
|
||||
result.y = y;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector3F setZ(const CVector3F &src, const float z)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return zyx(setX(zyx(src), z));
|
||||
#else
|
||||
CVector3F result = src;
|
||||
result.z = z;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F setZ(const CVector4F &src, const float z)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return zyxw(setX(zyxw(src), z));
|
||||
#else
|
||||
CVector4F result = src;
|
||||
result.z = z;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector4F setW(const CVector4F &src, const float w)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return wyzx(setX(wyzx(src), w));
|
||||
#else
|
||||
CVector4F result = src;
|
||||
result.w = w;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector2F splat2F(const float v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F s;
|
||||
s.mm = _mm_set_ps1(v);
|
||||
return s;
|
||||
#else
|
||||
CVector2F s;
|
||||
s.x = v;
|
||||
s.y = v;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F splat3F(const float v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F s;
|
||||
s.mm = _mm_set_ps1(v);
|
||||
return s;
|
||||
#else
|
||||
CVector3F s;
|
||||
s.x = v;
|
||||
s.y = v;
|
||||
s.z = v;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F set1F(const float x)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F s;
|
||||
s.mm = _mm_set_ss(x);
|
||||
return s;
|
||||
#else
|
||||
CVector1F s;
|
||||
s.x = x;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F set2F(const float x, const float y)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F s;
|
||||
s.mm = _mm_setr_ps(x, y, 0.0f, 0.0f);
|
||||
return s;
|
||||
#else
|
||||
CVector2F s;
|
||||
s.x = x;
|
||||
s.y = y;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F set3F(const CVector1F &x, const CVector1F &y, const CVector1F &z)
|
||||
{
|
||||
// todo: optimize
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F s;
|
||||
s.mm = _mm_setr_ps(getX(x), getX(y), getX(z), 0.0f);
|
||||
return s;
|
||||
#else
|
||||
CVector3F s;
|
||||
s.x = getX(x);
|
||||
s.y = getX(y);
|
||||
s.z = getX(z);
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F set3F(const float x, const float y, const float z)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F s;
|
||||
s.mm = _mm_setr_ps(x, y, z, 0.0f);
|
||||
return s;
|
||||
#else
|
||||
CVector3F s;
|
||||
s.x = x;
|
||||
s.y = y;
|
||||
s.z = z;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F set4F(const CVector2F &xy)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F s;
|
||||
s.mm = xy.mm; // z, w "undefined"
|
||||
return s;
|
||||
#else
|
||||
CVector4F s;
|
||||
s.x = getX(xy);
|
||||
s.y = getY(xy);
|
||||
// s.z = 0.0f;
|
||||
// s.w = 0.0f;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F set4F(const CVector3F &xyz)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F s;
|
||||
s.mm = xyz.mm; // w "undefined"
|
||||
return s;
|
||||
#else
|
||||
CVector4F s;
|
||||
s.x = getX(xyz);
|
||||
s.y = getY(xyz);
|
||||
s.z = getZ(xyz);
|
||||
// s.w = 0.0f;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F set4F(const CVector3F &xyz, const float w)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F s;
|
||||
s.mm = xyz.mm;
|
||||
s = setW(s, w);
|
||||
return s;
|
||||
#else
|
||||
CVector4F s;
|
||||
s.x = getX(xyz);
|
||||
s.y = getY(xyz);
|
||||
s.z = getZ(xyz);
|
||||
s.w = w;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F set4F(const float x, const float y, const float z, const float w)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F s;
|
||||
s.mm = _mm_setr_ps(x, y, z, w);
|
||||
return s;
|
||||
#else
|
||||
CVector4F s;
|
||||
s.x = x;
|
||||
s.y = y;
|
||||
s.z = z;
|
||||
s.w = w;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F zero1F()
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F z;
|
||||
z.mm = _mm_setzero_ps();
|
||||
return z;
|
||||
#else
|
||||
CVector1F z;
|
||||
z.x = 0.0f;
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F zero2F()
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F z;
|
||||
z.mm = _mm_setzero_ps();
|
||||
return z;
|
||||
#else
|
||||
CVector2F z;
|
||||
z.x = 0.0f;
|
||||
z.y = 0.0f;
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F zero3F()
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F z;
|
||||
z.mm = _mm_setzero_ps();
|
||||
return z;
|
||||
#else
|
||||
CVector3F z;
|
||||
z.x = 0.0f;
|
||||
z.y = 0.0f;
|
||||
z.z = 0.0f;
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector4F zero4F()
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F z;
|
||||
z.mm = _mm_setzero_ps();
|
||||
return z;
|
||||
#else
|
||||
CVector4F z;
|
||||
z.x = 0.0f;
|
||||
z.y = 0.0f;
|
||||
z.z = 0.0f;
|
||||
z.w = 0.0f;
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F splat4F(const float v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F s;
|
||||
s.mm = _mm_set_ps1(v);
|
||||
return s;
|
||||
#else
|
||||
CVector4F s;
|
||||
s.x = v;
|
||||
s.y = v;
|
||||
s.z = v;
|
||||
s.w = v;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector4F to4F(const CVector3F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F r;
|
||||
r.mm = v.mm;
|
||||
return r;
|
||||
#else
|
||||
CVector4F dst;
|
||||
dst.x = v.x;
|
||||
dst.y = v.y;
|
||||
dst.z = v.z;
|
||||
dst.w = 0.0f;
|
||||
return dst;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector3F to3F(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F r;
|
||||
r.mm = v.mm;
|
||||
return r;
|
||||
#else
|
||||
CVector3F dst;
|
||||
dst.x = v.x;
|
||||
dst.y = v.y;
|
||||
dst.z = v.z;
|
||||
return dst;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE void swapX(CVector1F &left, CVector1F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
#else
|
||||
float x = getX(left);
|
||||
left = set1F(getX(right));
|
||||
right = set1F(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE void swapX(CVector2F &left, CVector2F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
#else
|
||||
float x = getX(left);
|
||||
left = setX(left, getX(right));
|
||||
right = setX(right, x);
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE void swapX(CVector3F &left, CVector3F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
#else
|
||||
float x = getX(left);
|
||||
left = setX(left, getX(right));
|
||||
right = setX(right, x);
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE void swapX(CVector4F &left, CVector4F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
#else
|
||||
float x = getX(left);
|
||||
left = setX(left, getX(right));
|
||||
right = setX(right, x);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE void swapY(CVector2F &left, CVector2F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
left = yx(left);
|
||||
right = yx(right);
|
||||
CVector2F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
left = yx(left);
|
||||
right = yx(right);
|
||||
#else
|
||||
float y = getY(left);
|
||||
left = setY(left, getY(right));
|
||||
right = setY(right, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE void swapY(CVector3F &left, CVector3F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
left = yxz(left);
|
||||
right = yxz(right);
|
||||
CVector3F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
left = yxz(left);
|
||||
right = yxz(right);
|
||||
#else
|
||||
float y = getY(left);
|
||||
left = setY(left, getY(right));
|
||||
right = setY(right, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE void swapY(CVector4F &left, CVector4F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
left = yxzw(left);
|
||||
right = yxzw(right);
|
||||
CVector4F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
left = yxzw(left);
|
||||
right = yxzw(right);
|
||||
#else
|
||||
float y = getY(left);
|
||||
left = setY(left, getY(right));
|
||||
right = setY(right, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE void swapZ(CVector3F &left, CVector3F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
left = zyx(left);
|
||||
right = zyx(right);
|
||||
CVector3F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
left = zyx(left);
|
||||
right = zyx(right);
|
||||
#else
|
||||
float z = getZ(left);
|
||||
left = setZ(left, getZ(right));
|
||||
right = setZ(right, z);
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE void swapZ(CVector4F &left, CVector4F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
left = zyxw(left);
|
||||
right = zyxw(right);
|
||||
CVector4F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
left = zyxw(left);
|
||||
right = zyxw(right);
|
||||
#else
|
||||
float z = getZ(left);
|
||||
left = setZ(left, getZ(right));
|
||||
right = setZ(right, z);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE void swapW(CVector4F &left, CVector4F &right)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
left = wyzx(left);
|
||||
right = wyzx(right);
|
||||
CVector4F cache = left;
|
||||
left.mm = _mm_move_ss(left.mm, right.mm);
|
||||
right.mm = _mm_move_ss(right.mm, cache.mm);
|
||||
left = wyzx(left);
|
||||
right = wyzx(right);
|
||||
#else
|
||||
float w = getW(left);
|
||||
left = setW(left, getW(right));
|
||||
right = setW(right, w);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} /* namespace NLMISC */
|
||||
|
||||
#endif /* #ifndef NLMISC_VECTORF_ACCESSORS_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,711 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2014, Jan BOON
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NLMISC_VECTORF_MATH_H
|
||||
#define NLMISC_VECTORF_MATH_H
|
||||
#include "types_nl.h"
|
||||
|
||||
// System includes
|
||||
#ifdef NL_HAS_SSE2
|
||||
# include <xmmintrin.h>
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NLMISC includes
|
||||
#include "types_nl.h"
|
||||
|
||||
// Project includes
|
||||
|
||||
#ifdef min
|
||||
# undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
# undef max
|
||||
#endif
|
||||
|
||||
namespace NLMISC {
|
||||
|
||||
NL_FORCE_INLINE CVector1F add(const CVector1F &l, const CVector1F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F m;
|
||||
m.mm = _mm_add_ss(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector1F a;
|
||||
a.x = l.x + r.x;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F add(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F m;
|
||||
m.mm = _mm_add_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector2F a;
|
||||
a.x = l.x + r.x;
|
||||
a.y = l.y + r.y;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F add(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F m;
|
||||
m.mm = _mm_add_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector3F a;
|
||||
a.x = l.x + r.x;
|
||||
a.y = l.y + r.y;
|
||||
a.z = l.z + r.z;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F add(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F m;
|
||||
m.mm = _mm_add_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector4F a;
|
||||
a.x = l.x + r.x;
|
||||
a.y = l.y + r.y;
|
||||
a.z = l.z + r.z;
|
||||
a.w = l.w + r.w;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F sub(const CVector1F &l, const CVector1F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F m;
|
||||
m.mm = _mm_sub_ss(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector1F a;
|
||||
a.x = l.x - r.x;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F sub(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F m;
|
||||
m.mm = _mm_sub_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector2F a;
|
||||
a.x = l.x - r.x;
|
||||
a.y = l.y - r.y;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F sub(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F m;
|
||||
m.mm = _mm_sub_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector3F a;
|
||||
a.x = l.x - r.x;
|
||||
a.y = l.y - r.y;
|
||||
a.z = l.z - r.z;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F sub(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F m;
|
||||
m.mm = _mm_sub_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector4F a;
|
||||
a.x = l.x - r.x;
|
||||
a.y = l.y - r.y;
|
||||
a.z = l.z - r.z;
|
||||
a.w = l.w - r.w;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F mul(const CVector1F &l, const CVector1F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F m;
|
||||
m.mm = _mm_mul_ss(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector1F a;
|
||||
a.x = l.x * r.x;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F mul(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F m;
|
||||
m.mm = _mm_mul_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector2F a;
|
||||
a.x = l.x * r.x;
|
||||
a.y = l.y * r.y;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F mul(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F m;
|
||||
m.mm = _mm_mul_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector3F a;
|
||||
a.x = l.x * r.x;
|
||||
a.y = l.y * r.y;
|
||||
a.z = l.z * r.z;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F mul(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F m;
|
||||
m.mm = _mm_mul_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector4F a;
|
||||
a.x = l.x * r.x;
|
||||
a.y = l.y * r.y;
|
||||
a.z = l.z * r.z;
|
||||
a.w = l.w * r.w;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F div(const CVector1F &l, const CVector1F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F m;
|
||||
m.mm = _mm_div_ss(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector1F a;
|
||||
a.x = l.x / r.x;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F div(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F m;
|
||||
m.mm = _mm_div_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector2F a;
|
||||
a.x = l.x / r.x;
|
||||
a.y = l.y / r.y;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F div(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F m;
|
||||
m.mm = _mm_div_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector3F a;
|
||||
a.x = l.x / r.x;
|
||||
a.y = l.y / r.y;
|
||||
a.z = l.z / r.z;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F div(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F m;
|
||||
m.mm = _mm_div_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector4F a;
|
||||
a.x = l.x / r.x;
|
||||
a.y = l.y / r.y;
|
||||
a.z = l.z / r.z;
|
||||
a.w = l.w / r.w;
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F sqrtF(const CVector1F &v)
|
||||
{
|
||||
#if (NL_HAS_SSE2 && NL_HAS_SSE2)
|
||||
CVector1F s;
|
||||
s.mm = _mm_sqrt_ss(v.mm);
|
||||
return s;
|
||||
#else
|
||||
CVector1F s;
|
||||
s.x = sqrtf(v.x);
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F sqrtF(const CVector2F &v)
|
||||
{
|
||||
#if (NL_HAS_SSE2 && NL_HAS_SSE2)
|
||||
CVector2F s;
|
||||
s.mm = _mm_sqrt_ps(v.mm);
|
||||
return s;
|
||||
#else
|
||||
CVector2F s;
|
||||
s.x = sqrtf(v.x);
|
||||
s.y = sqrtf(v.y);
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F sqrtF(const CVector3F &v)
|
||||
{
|
||||
#if (NL_HAS_SSE2 && NL_HAS_SSE2)
|
||||
CVector3F s;
|
||||
s.mm = _mm_sqrt_ps(v.mm);
|
||||
return s;
|
||||
#else
|
||||
CVector3F s;
|
||||
s.x = sqrtf(v.x);
|
||||
s.y = sqrtf(v.y);
|
||||
s.z = sqrtf(v.z);
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F sqrtF(const CVector4F &v)
|
||||
{
|
||||
#if (NL_HAS_SSE2 && NL_HAS_SSE2)
|
||||
CVector4F s;
|
||||
s.mm = _mm_sqrt_ps(v.mm);
|
||||
return s;
|
||||
#else
|
||||
CVector4F s;
|
||||
s.x = sqrtf(v.x);
|
||||
s.y = sqrtf(v.y);
|
||||
s.z = sqrtf(v.z);
|
||||
s.w = sqrtf(v.w);
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F accumulate(const CVector2F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return add(x(v), y(v));
|
||||
#else
|
||||
CVector1F result;
|
||||
result.x = v.x + v.y;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F accumulate(const CVector3F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return add(add(x(v), y(v)), z(v));
|
||||
#else
|
||||
CVector1F result;
|
||||
result.x = v.x + v.y + v.z;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F accumulate(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return accumulate(add(xy(v), zw(v)));
|
||||
#else
|
||||
CVector1F result;
|
||||
result.x = v.x + v.y + v.z + v.w;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector3F cross(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
return sub(mul(yzx(l), zxy(r)), mul(zxy(l), yzx(r)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector1F dot(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
CVector2F mult = mul(l, r);
|
||||
CVector1F result = accumulate(mult);
|
||||
return result;
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F dot(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
CVector3F mult = mul(l, r);
|
||||
CVector1F result = accumulate(mult);
|
||||
return result;
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F dotSplat(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
return xx(dot(l, r));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F dotSplat(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
return xxx(dot(l, r));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F lengthSq(const CVector2F &v)
|
||||
{
|
||||
return dot(v, v);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F lengthSq(const CVector3F &v)
|
||||
{
|
||||
return dot(v, v);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F lengthSqSplat(const CVector2F &v)
|
||||
{
|
||||
return dotSplat(v, v);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F lengthSqSplat(const CVector3F &v)
|
||||
{
|
||||
return dotSplat(v, v);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F length(const CVector2F &v)
|
||||
{
|
||||
return sqrtF(lengthSq(v));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F length(const CVector3F &v)
|
||||
{
|
||||
return sqrtF(lengthSq(v));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F lengthSplat(const CVector2F &v)
|
||||
{
|
||||
return xx(length(v));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F lengthSplat(const CVector3F &v)
|
||||
{
|
||||
return xxx(length(v));
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector2F normalize(const CVector2F &v)
|
||||
{
|
||||
return div(v, lengthSplat(v));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F normalize(const CVector3F &v)
|
||||
{
|
||||
return div(v, lengthSplat(v));
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F minF(const CVector1F &l, const CVector1F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F m;
|
||||
m.mm = _mm_min_ss(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector1F m;
|
||||
m.x = min(l.x, r.x);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector1F maxF(const CVector1F &l, const CVector1F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector1F m;
|
||||
m.mm = _mm_max_ss(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector1F m;
|
||||
m.x = max(l.x, r.x);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F minF(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F m;
|
||||
m.mm = _mm_min_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector2F m;
|
||||
m.x = min(l.x, r.x);
|
||||
m.y = min(l.y, r.y);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector2F maxF(const CVector2F &l, const CVector2F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector2F m;
|
||||
m.mm = _mm_max_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector2F m;
|
||||
m.x = max(l.x, r.x);
|
||||
m.y = max(l.y, r.y);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F minF(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F m;
|
||||
m.mm = _mm_min_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector3F m;
|
||||
m.x = min(l.x, r.x);
|
||||
m.y = min(l.y, r.y);
|
||||
m.z = min(l.z, r.z);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F maxF(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector3F m;
|
||||
m.mm = _mm_max_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector3F m;
|
||||
m.x = max(l.x, r.x);
|
||||
m.y = max(l.y, r.y);
|
||||
m.z = max(l.z, r.z);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector4F minF(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F m;
|
||||
m.mm = _mm_min_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector4F m;
|
||||
m.x = min(l.x, r.x);
|
||||
m.y = min(l.y, r.y);
|
||||
m.z = min(l.z, r.z);
|
||||
m.w = min(l.w, r.w);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F maxF(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
CVector4F m;
|
||||
m.mm = _mm_max_ps(l.mm, r.mm);
|
||||
return m;
|
||||
#else
|
||||
CVector4F m;
|
||||
m.x = max(l.x, r.x);
|
||||
m.y = max(l.y, r.y);
|
||||
m.z = max(l.z, r.z);
|
||||
m.w = max(l.w, r.w);
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector3F average(const CVector3F &v0, const CVector3F &v1)
|
||||
{
|
||||
CVector3F divider = splat3F(1.0f / 2.0f);
|
||||
return mul(add(v0, v1), divider);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F average(const CVector3F &v0, const CVector3F &v1, const CVector3F &v2)
|
||||
{
|
||||
CVector3F divider = splat3F(1.0f / 3.0f);
|
||||
return mul(add(add(v0, v1), v2), divider);
|
||||
}
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector3F average(const CVector3F &v0, const CVector3F &v1, const CVector3F &v2, const CVector3F &v3)
|
||||
{
|
||||
CVector3F divider = splat3F(1.0f / 4.0f);
|
||||
return mul(add(add(add(v0, v1), v2), v3), divider);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector4F average(const CVector4F &v0, const CVector4F &v1)
|
||||
{
|
||||
CVector4F divider = splat4F(1.0f / 2.0f);
|
||||
return mul(add(v0, v1), divider);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F average(const CVector4F &v0, const CVector4F &v1, const CVector4F &v2)
|
||||
{
|
||||
CVector4F divider = splat4F(1.0f / 3.0f);
|
||||
return mul(add(add(v0, v1), v2), divider);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F average(const CVector4F &v0, const CVector4F &v1, const CVector4F &v2, const CVector4F &v3)
|
||||
{
|
||||
CVector4F divider = splat4F(1.0f / 4.0f);
|
||||
return mul(add(add(add(v0, v1), v2), v3), divider);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE CVector3F lerp(const CVector3F &l, const CVector3F &r, const CVector3F &a)
|
||||
{
|
||||
CVector3F one = splat3F(1.0f);
|
||||
CVector3F lmul = mul(l, sub(one, a));
|
||||
CVector3F rmul = mul(r, a);
|
||||
return add(lmul, rmul);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector3F lerp(const CVector3F &l, const CVector3F &r, const float a)
|
||||
{
|
||||
CVector3F va = splat3F(a);
|
||||
return lerp(l, r, va);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F lerp(const CVector4F &l, const CVector4F &r, const CVector4F &a)
|
||||
{
|
||||
CVector4F one = splat4F(1.0f);
|
||||
CVector4F lmul = mul(l, sub(one, a));
|
||||
CVector4F rmul = mul(r, a);
|
||||
return add(lmul, rmul);
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE CVector4F lerp(const CVector4F &l, const CVector4F &r, const float a)
|
||||
{
|
||||
CVector4F va = splat4F(a);
|
||||
return lerp(l, r, va);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/// Add all the elements inside one float and splat them
|
||||
// accumulate()
|
||||
NL_FORCE_INLINE CVector4F accumulateSplat(const CVector4F &v)
|
||||
{
|
||||
#ifdef NL_HAS_SSE3
|
||||
CVector4F result;
|
||||
result.mm = _mm_hadd_ps(v.mm, v.mm);
|
||||
result.mm = _mm_hadd_ps(result.mm, result.mm);
|
||||
return result;
|
||||
#else
|
||||
CVector4F result;
|
||||
result.x = v.x + v.y + v.z + v.w;
|
||||
result.y = result.x;
|
||||
result.z = result.x;
|
||||
result.w = result.x;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
NL_ASSIMILATE_BI_FUNCTION(CVector2F, minF, const CVector2F &)
|
||||
NL_ASSIMILATE_BI_FUNCTION(CVector2F, maxF, const CVector2F &)
|
||||
|
||||
NL_ASSIMILATE_BI_FUNCTION(CVector3F, minF, const CVector3F &)
|
||||
NL_ASSIMILATE_BI_FUNCTION(CVector3F, maxF, const CVector3F &)
|
||||
|
||||
NL_ASSIMILATE_BI_FUNCTION(CVector4F, minF, const CVector4F &)
|
||||
NL_ASSIMILATE_BI_FUNCTION(CVector4F, maxF, const CVector4F &)
|
||||
|
||||
|
||||
NL_CLAMP_USING_MIN_MAX(CVector1F, const CVector1F &)
|
||||
NL_CLAMP_USING_MIN_MAX(CVector2F, const CVector2F &)
|
||||
NL_CLAMP_USING_MIN_MAX(CVector3F, const CVector3F &)
|
||||
NL_CLAMP_USING_MIN_MAX(CVector4F, const CVector4F &)
|
||||
|
||||
|
||||
} /* namespace NLMISC */
|
||||
|
||||
#endif /* #ifndef NLMISC_VECTORF_MATH_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2014, Jan BOON
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NLMISC_VECTORF_MISC_H
|
||||
#define NLMISC_VECTORF_MISC_H
|
||||
#include "types_nl.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// NLMISC includes
|
||||
|
||||
// Project includes
|
||||
|
||||
|
||||
|
||||
#define NL_ASSIMILATE_BI_FUNCTION(__return_type, __function_name, __parameter_type) \
|
||||
NL_FORCE_INLINE __return_type __function_name(__parameter_type v0, __parameter_type v1, __parameter_type v2) \
|
||||
{ \
|
||||
return __function_name(__function_name(v0, v1), v2); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type __function_name(__parameter_type v0, __parameter_type v1, __parameter_type v2, __parameter_type v3) \
|
||||
{ \
|
||||
return __function_name(__function_name(__function_name(v0, v1), v2), v3); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type __function_name(__parameter_type v0, __parameter_type v1, __parameter_type v2, __parameter_type v3, __parameter_type v4) \
|
||||
{ \
|
||||
return __function_name(__function_name(__function_name(__function_name(v0, v1), v2), v3), v4); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type __function_name(__parameter_type v0, __parameter_type v1, __parameter_type v2, __parameter_type v3, __parameter_type v4, __parameter_type v5) \
|
||||
{ \
|
||||
return __function_name(__function_name(__function_name(__function_name(__function_name(v0, v1), v2), v3), v4), v5); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type __function_name(__parameter_type v0, __parameter_type v1, __parameter_type v2, __parameter_type v3, __parameter_type v4, __parameter_type v5, __parameter_type v6) \
|
||||
{ \
|
||||
return __function_name(__function_name(__function_name(__function_name(__function_name(__function_name(v0, v1), v2), v3), v4), v5), v6); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type __function_name(__parameter_type v0, __parameter_type v1, __parameter_type v2, __parameter_type v3, __parameter_type v4, __parameter_type v5, __parameter_type v6, __parameter_type v7) \
|
||||
{ \
|
||||
return __function_name(__function_name(__function_name(__function_name(__function_name(__function_name(__function_name(v0, v1), v2), v3), v4), v5), v6), v7); \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
#define NL_CLAMP_USING_MIN_MAX(__return_type, __parameter_type) \
|
||||
NL_FORCE_INLINE __return_type clamp(__parameter_type value, __parameter_type minValue, __parameter_type maxValue) \
|
||||
{ \
|
||||
return minF(maxF(minValue, value), maxValue); \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
#define NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB(__return_type, __ref_return_type, __in_parameter_type, __out_parameter_type) \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type operator+(__in_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
return add(l, r); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __ref_return_type operator+=(__out_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
l = add(l, r); \
|
||||
return l; \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type operator-(__in_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
return sub(l, r); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __ref_return_type operator-=(__out_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
l = sub(l, r); \
|
||||
return l; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
#define NL_MATH_OPERATORS_USING_FUNCTIONS_MUL_DIV(__return_type, __ref_return_type, __in_parameter_type, __out_parameter_type) \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type operator*(__in_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
return mul(l, r); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __ref_return_type operator*=(__out_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
l = mul(l, r); \
|
||||
return l; \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __return_type operator/(__in_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
return div(l, r); \
|
||||
} \
|
||||
\
|
||||
NL_FORCE_INLINE __ref_return_type operator/=(__out_parameter_type l, __in_parameter_type r) \
|
||||
{ \
|
||||
l = div(l, r); \
|
||||
return l; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
#define NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB_MUL_DIV(__return_type, __ref_return_type, __in_parameter_type, __out_parameter_type) \
|
||||
\
|
||||
NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB(__return_type, __ref_return_type, __in_parameter_type, __out_parameter_type) \
|
||||
NL_MATH_OPERATORS_USING_FUNCTIONS_MUL_DIV(__return_type, __ref_return_type, __in_parameter_type, __out_parameter_type) \
|
||||
|
||||
|
||||
|
||||
namespace NLMISC {
|
||||
|
||||
} /* namespace NLMISC */
|
||||
|
||||
#endif /* #ifndef NLMISC_VECTORF_MISC_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2014, Jan BOON
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NLMISC_VECTORF_OPERATORS_H
|
||||
#define NLMISC_VECTORF_OPERATORS_H
|
||||
#include "types_nl.h"
|
||||
|
||||
// System includes
|
||||
#ifdef NL_HAS_SSE2
|
||||
# include <xmmintrin.h>
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
// STL includes
|
||||
|
||||
// NLMISC includes
|
||||
|
||||
// Project includes
|
||||
|
||||
namespace NLMISC {
|
||||
|
||||
|
||||
NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB_MUL_DIV(CVector1F, CVector1F &, const CVector1F &, CVector1F &)
|
||||
NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB(CVector2F, CVector2F &, const CVector2F &, CVector2F &)
|
||||
NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB(CVector3F, CVector3F &, const CVector3F &, CVector3F &)
|
||||
NL_MATH_OPERATORS_USING_FUNCTIONS_ADD_SUB(CVector4F, CVector4F &, const CVector4F &, CVector4F &)
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE bool operator==(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return (_mm_movemask_ps(_mm_cmpeq_ps(l.mm, r.mm)) & 0x07) == 0x07;
|
||||
#else
|
||||
return l.x == r.x && l.y == r.y && l.z == r.z;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE bool operator!=(const CVector3F &l, const CVector3F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return (_mm_movemask_ps(_mm_cmpneq_ps(l.mm, r.mm)) & 0x07) != 0;
|
||||
#else
|
||||
return l.x != r.x || l.y != r.y || l.z != r.z;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
NL_FORCE_INLINE bool operator==(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return (_mm_movemask_ps(_mm_cmpeq_ps(l.mm, r.mm)) & 0x0F) == 0x0F;
|
||||
#else
|
||||
return l.x == r.x && l.y == r.y && l.z == r.z && l.w == r.w;
|
||||
#endif
|
||||
}
|
||||
|
||||
NL_FORCE_INLINE bool operator!=(const CVector4F &l, const CVector4F &r)
|
||||
{
|
||||
#ifdef NL_HAS_SSE2
|
||||
return (_mm_movemask_ps(_mm_cmpneq_ps(l.mm, r.mm)) & 0x0F) != 0;
|
||||
#else
|
||||
return l.x != r.x || l.y != r.y || l.z != r.z || l.w != r.w;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
} /* namespace NLMISC */
|
||||
|
||||
#endif /* #ifndef NLMISC_VECTORF_OPERATORS_H */
|
||||
|
||||
/* end of file */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,75 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2014, Jan BOON
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NLMISC_VECTORF_TYPES_H
|
||||
#define NLMISC_VECTORF_TYPES_H
|
||||
#include "types_nl.h"
|
||||
|
||||
// System includes
|
||||
#ifdef NL_HAS_SSE2
|
||||
# include <xmmintrin.h>
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
// STL includes
|
||||
|
||||
// NLMISC includes
|
||||
|
||||
// Project includes
|
||||
|
||||
namespace NLMISC {
|
||||
|
||||
#ifdef NL_HAS_SSE2
|
||||
typedef NL_ALIGN_SSE2 struct { __m128 mm; } CVector1F; // 12 of 16 bytes wasted
|
||||
#else
|
||||
typedef struct { float x; } CVector1F;
|
||||
#endif
|
||||
|
||||
#ifdef NL_HAS_SSE2
|
||||
typedef NL_ALIGN_SSE2 struct { __m128 mm; } CVector2F; // 8 of 16 bytes wasted
|
||||
#else
|
||||
typedef struct { float x, y; } CVector2F;
|
||||
#endif
|
||||
|
||||
#ifdef NL_HAS_SSE2
|
||||
typedef NL_ALIGN_SSE2 struct { __m128 mm; } CVector3F; // 4 of 16 bytes wasted
|
||||
#else
|
||||
typedef struct { float x, y, z; } CVector3F;
|
||||
#endif
|
||||
|
||||
#ifdef NL_HAS_SSE2
|
||||
typedef NL_ALIGN_SSE2 struct { __m128 mm; } CVector4F;
|
||||
#else
|
||||
typedef struct { float x, y, z, w; } CVector4F;
|
||||
#endif
|
||||
|
||||
} /* namespace NLMISC */
|
||||
|
||||
#endif /* #ifndef NLMISC_VECTORF_TYPES_H */
|
||||
|
||||
/* end of file */
|
Loading…
Reference in New Issue