mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-15 06:00:12 +00:00
197 lines
4.4 KiB
C++
197 lines
4.4 KiB
C++
// Bullet Continuous Collision Detection and Physics Library
|
|
// Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
|
//
|
|
//
|
|
// Scalar.inl
|
|
//
|
|
// Copyright (c) 2006 Simon Hobbs
|
|
//
|
|
// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source distribution.
|
|
#pragma once
|
|
|
|
|
|
inline Scalar::Scalar()
|
|
{
|
|
}
|
|
|
|
inline Scalar::Scalar(float f)
|
|
{
|
|
base = _mm_set1_ps(f);
|
|
}
|
|
|
|
|
|
inline Scalar::Scalar(int i, bool forceNoConvert)
|
|
{
|
|
__declspec(align(16)) int iv[4] = {i, i, i, i};
|
|
*(Scalar*)&base = *(Scalar*)&iv;
|
|
}
|
|
|
|
inline Scalar::Scalar(__m128 s)
|
|
{
|
|
base = s;
|
|
}
|
|
|
|
inline Scalar::Scalar(int i)
|
|
{
|
|
base = _mm_cvtsi32_ss(base, i);
|
|
base = _mm_shuffle_ps(base, base, _MM_SHUFFLE(0, 0, 0, 0));
|
|
}
|
|
|
|
inline const Scalar& Scalar::operator=(const Scalar &a)
|
|
{
|
|
base = a.base;
|
|
return *this;
|
|
}
|
|
|
|
inline Scalar::operator const float() const
|
|
{
|
|
float f;
|
|
_mm_store_ss(&f, base);
|
|
return f;
|
|
}
|
|
|
|
inline Scalar::operator const float()
|
|
{
|
|
float f;
|
|
_mm_store_ss(&f, base);
|
|
return f;
|
|
}
|
|
|
|
inline void Scalar::operator+=(const Scalar& b)
|
|
{
|
|
base = _mm_add_ps(base, b.base);
|
|
}
|
|
|
|
inline void Scalar::operator-=(const Scalar& b)
|
|
{
|
|
base = _mm_sub_ps(base, b.base);
|
|
}
|
|
|
|
inline void Scalar::operator*=(const Scalar& b)
|
|
{
|
|
base = _mm_mul_ps(base, b.base);
|
|
}
|
|
|
|
inline void Scalar::operator/=(const Scalar& b)
|
|
{
|
|
base = _mm_div_ps(base, b.base);
|
|
}
|
|
|
|
inline const Scalar operator-(const Scalar& a)
|
|
{
|
|
return Scalar(_mm_sub_ps(_mm_setzero_ps(), a.base));
|
|
}
|
|
|
|
inline const Scalar Abs(const Scalar& a)
|
|
{
|
|
return Scalar(_mm_and_ps(a.base, Scalar::Consts::AbsMask.base));
|
|
}
|
|
|
|
inline const Scalar Rcp(const Scalar& a)
|
|
{
|
|
return Scalar(_mm_rcp_ps(a.base));
|
|
}
|
|
|
|
inline const Scalar Rsqrt(const Scalar& a)
|
|
{
|
|
return Scalar(_mm_rsqrt_ps(a.base));
|
|
}
|
|
|
|
inline const Scalar Sqrt(const Scalar& a)
|
|
{
|
|
return Scalar(_mm_sqrt_ps(a.base));
|
|
}
|
|
|
|
// Newton Raphson Reciprocal
|
|
// (2 * Rcp(x)) - (x * Rcp(x) * Rcp(x))]
|
|
inline const Scalar RcpNr(const Scalar& a)
|
|
{
|
|
Scalar rcp = Rcp(a);
|
|
return (rcp + rcp) - (a * rcp * rcp);
|
|
}
|
|
|
|
// Newton Raphson Reciprocal Square Root
|
|
// 0.5 * Rsqrt * (3 - x * Rsqrt(x) * Rsqrt(x))
|
|
inline const Scalar RsqrtNr(const Scalar& a)
|
|
{
|
|
Scalar rcp = Rsqrt(a);
|
|
return (Scalar::Consts::Half * rcp) * (Scalar::Consts::Three - (a * rcp) * rcp);
|
|
}
|
|
|
|
// binary
|
|
inline const Scalar operator+(const Scalar& a, const Scalar& b)
|
|
{
|
|
return Scalar(_mm_add_ps(a.base, b.base));
|
|
}
|
|
|
|
inline const Scalar operator-(const Scalar& a, const Scalar& b)
|
|
{
|
|
return Scalar(_mm_sub_ps(a.base, b.base));
|
|
}
|
|
|
|
inline const Scalar operator*(const Scalar& a, const Scalar& b)
|
|
{
|
|
return Scalar(_mm_mul_ps(a.base, b.base));
|
|
}
|
|
|
|
inline const Scalar operator/(const Scalar& a, const Scalar& b)
|
|
{
|
|
return Scalar(_mm_div_ps(a.base, b.base));
|
|
}
|
|
|
|
inline const Scalar Min(const Scalar& a, const Scalar& b)
|
|
{
|
|
return Scalar(_mm_min_ps(a.base, b.base));
|
|
}
|
|
|
|
inline const Scalar Max(const Scalar& a, const Scalar& b)
|
|
{
|
|
return Scalar(_mm_max_ps(a.base, b.base));
|
|
}
|
|
|
|
inline const Scalar Clamp(const Scalar& a, const Scalar& min, const Scalar& max)
|
|
{
|
|
return Scalar(_mm_min_ps(max.base, _mm_max_ps(min.base, a.base)));
|
|
}
|
|
|
|
inline const Scalar Lerp(const Scalar& a, const Scalar& b, const Scalar& t)
|
|
{
|
|
return Scalar(a + (b - a) * t);
|
|
}
|
|
|
|
inline const int IsNegative(const Scalar& a)
|
|
{
|
|
return _mm_movemask_ps(a.base) & 1;
|
|
}
|
|
|
|
// warning. this only checks for quiet nan
|
|
inline const int IsNan(const Scalar& a)
|
|
{
|
|
int aInt = *(int*)&a;
|
|
return ((aInt & 0x7fc00000) == 0x7fc00000);
|
|
}
|
|
|
|
inline const int IsInfinity(const Scalar& a)
|
|
{
|
|
return (a == Scalar::Consts::PosInfinity || a == Scalar::Consts::NegInfinity);
|
|
}
|
|
|
|
inline const int IsPosInfinity(const Scalar& a)
|
|
{
|
|
return (a == Scalar::Consts::PosInfinity);
|
|
}
|
|
|
|
inline const int IsNegInfinity(const Scalar& a)
|
|
{
|
|
return (a == Scalar::Consts::NegInfinity);
|
|
}
|
|
|