forked from bartvdbraak/blender
feb4f51103
Only windows projectfiles for now. Will ask Hans to get unix makefiles done.
397 lines
8.3 KiB
C++
397 lines
8.3 KiB
C++
/*
|
|
|
|
Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com>
|
|
|
|
Permission is hereby granted, free of charge, to any person or organization
|
|
obtaining a copy of the software and accompanying documentation covered by
|
|
this license (the "Software") to use, reproduce, display, distribute,
|
|
execute, and transmit the Software, and to prepare derivative works of the
|
|
Software, and to permit third-parties to whom the Software is furnished to
|
|
do so, all subject to the following:
|
|
|
|
The copyright notices in the Software and this entire statement, including
|
|
the above license grant, this restriction and the following disclaimer,
|
|
must be included in all copies of the Software, in whole or in part, and
|
|
all derivative works of the Software, unless such copies or derivative
|
|
works are solely in the form of machine-executable object code generated by
|
|
a source language processor.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
|
|
#ifndef SIMD__VECTOR3_H
|
|
#define SIMD__VECTOR3_H
|
|
|
|
#include "SimdQuadWord.h"
|
|
|
|
|
|
///SimdVector3 is 16byte aligned, and has an extra unused component m_w
|
|
///this extra component can be used by derived classes (Quaternion?) or by user
|
|
class SimdVector3 : public SimdQuadWord {
|
|
|
|
|
|
public:
|
|
SIMD_FORCE_INLINE SimdVector3() {}
|
|
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z)
|
|
:SimdQuadWord(x,y,z,0.f)
|
|
{
|
|
}
|
|
|
|
// SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
|
|
// : SimdQuadWord(x,y,z,w)
|
|
// {
|
|
// }
|
|
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdVector3& operator+=(const SimdVector3& v)
|
|
{
|
|
m_x += v.x(); m_y += v.y(); m_z += v.z();
|
|
return *this;
|
|
}
|
|
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdVector3& operator-=(const SimdVector3& v)
|
|
{
|
|
m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
|
|
return *this;
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdScalar& s)
|
|
{
|
|
m_x *= s; m_y *= s; m_z *= s;
|
|
return *this;
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3& operator/=(const SimdScalar& s)
|
|
{
|
|
assert(s != SimdScalar(0.0));
|
|
return *this *= SimdScalar(1.0) / s;
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar dot(const SimdVector3& v) const
|
|
{
|
|
return m_x * v.x() + m_y * v.y() + m_z * v.z();
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar length2() const
|
|
{
|
|
return dot(*this);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar length() const
|
|
{
|
|
return sqrtf(length2());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar distance2(const SimdVector3& v) const;
|
|
|
|
SIMD_FORCE_INLINE SimdScalar distance(const SimdVector3& v) const;
|
|
|
|
SIMD_FORCE_INLINE SimdVector3& normalize()
|
|
{
|
|
return *this /= length();
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3 normalized() const;
|
|
|
|
SIMD_FORCE_INLINE SimdScalar angle(const SimdVector3& v) const
|
|
{
|
|
SimdScalar s = sqrtf(length2() * v.length2());
|
|
assert(s != SimdScalar(0.0));
|
|
return acosf(dot(v) / s);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3 absolute() const
|
|
{
|
|
return SimdVector3(
|
|
fabsf(m_x),
|
|
fabsf(m_y),
|
|
fabsf(m_z));
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3 cross(const SimdVector3& v) const
|
|
{
|
|
return SimdVector3(
|
|
m_y * v.z() - m_z * v.y(),
|
|
m_z * v.x() - m_x * v.z(),
|
|
m_x * v.y() - m_y * v.x());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar triple(const SimdVector3& v1, const SimdVector3& v2) const
|
|
{
|
|
return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) +
|
|
m_y * (v1.z() * v2.x() - v1.x() * v2.z()) +
|
|
m_z * (v1.x() * v2.y() - v1.y() * v2.x());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE int minAxis() const
|
|
{
|
|
return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE int maxAxis() const
|
|
{
|
|
return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE int furthestAxis() const
|
|
{
|
|
return absolute().minAxis();
|
|
}
|
|
|
|
SIMD_FORCE_INLINE int closestAxis() const
|
|
{
|
|
return absolute().maxAxis();
|
|
}
|
|
|
|
SIMD_FORCE_INLINE void setInterpolate3(const SimdVector3& v0, const SimdVector3& v1, SimdScalar rt)
|
|
{
|
|
SimdScalar s = 1.0f - rt;
|
|
m_x = s * v0[0] + rt * v1.x();
|
|
m_y = s * v0[1] + rt * v1.y();
|
|
m_z = s * v0[2] + rt * v1.z();
|
|
//don't do the unused w component
|
|
// m_co[3] = s * v0[3] + rt * v1[3];
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3 lerp(const SimdVector3& v, const SimdScalar& t) const
|
|
{
|
|
return SimdVector3(m_x + (v.x() - m_x) * t,
|
|
m_y + (v.y() - m_y) * t,
|
|
m_z + (v.z() - m_z) * t);
|
|
}
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdVector3& v)
|
|
{
|
|
m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
|
|
return *this;
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator+(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return SimdVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator*(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return SimdVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() *+ v2.z());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator-(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return SimdVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator-(const SimdVector3& v)
|
|
{
|
|
return SimdVector3(-v.x(), -v.y(), -v.z());
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator*(const SimdVector3& v, const SimdScalar& s)
|
|
{
|
|
return SimdVector3(v.x() * s, v.y() * s, v.z() * s);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator*(const SimdScalar& s, const SimdVector3& v)
|
|
{
|
|
return v * s;
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
operator/(const SimdVector3& v, const SimdScalar& s)
|
|
{
|
|
assert(s != SimdScalar(0.0));
|
|
return v * (SimdScalar(1.0) / s);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar
|
|
dot(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return v1.dot(v2);
|
|
}
|
|
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdScalar
|
|
distance2(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return v1.distance2(v2);
|
|
}
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdScalar
|
|
distance(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return v1.distance(v2);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar
|
|
angle(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return v1.angle(v2);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
cross(const SimdVector3& v1, const SimdVector3& v2)
|
|
{
|
|
return v1.cross(v2);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar
|
|
triple(const SimdVector3& v1, const SimdVector3& v2, const SimdVector3& v3)
|
|
{
|
|
return v1.triple(v2, v3);
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3
|
|
lerp(const SimdVector3& v1, const SimdVector3& v2, const SimdScalar& t)
|
|
{
|
|
return v1.lerp(v2, t);
|
|
}
|
|
|
|
|
|
SIMD_FORCE_INLINE bool operator==(const SimdVector3& p1, const SimdVector3& p2)
|
|
{
|
|
return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2];
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar SimdVector3::distance2(const SimdVector3& v) const
|
|
{
|
|
return (v - *this).length2();
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdScalar SimdVector3::distance(const SimdVector3& v) const
|
|
{
|
|
return (v - *this).length();
|
|
}
|
|
|
|
SIMD_FORCE_INLINE SimdVector3 SimdVector3::normalized() const
|
|
{
|
|
return *this / length();
|
|
}
|
|
|
|
class SimdVector4 : public SimdVector3
|
|
{
|
|
public:
|
|
|
|
SIMD_FORCE_INLINE SimdVector4() {}
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdVector4(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w)
|
|
: SimdVector3(x,y,z)
|
|
{
|
|
m_unusedW = w;
|
|
}
|
|
|
|
|
|
SIMD_FORCE_INLINE SimdVector4 absolute4() const
|
|
{
|
|
return SimdVector4(
|
|
fabsf(m_x),
|
|
fabsf(m_y),
|
|
fabsf(m_z),
|
|
fabsf(m_unusedW));
|
|
}
|
|
|
|
|
|
|
|
float getW() const { return m_unusedW;}
|
|
|
|
|
|
SIMD_FORCE_INLINE int maxAxis4() const
|
|
{
|
|
int maxIndex = -1;
|
|
float maxVal = -1e30f;
|
|
if (m_x > maxVal)
|
|
{
|
|
maxIndex = 0;
|
|
maxVal = m_x;
|
|
}
|
|
if (m_y > maxVal)
|
|
{
|
|
maxIndex = 1;
|
|
maxVal = m_y;
|
|
}
|
|
if (m_z > maxVal)
|
|
{
|
|
maxIndex = 2;
|
|
maxVal = m_z;
|
|
}
|
|
if (m_unusedW > maxVal)
|
|
{
|
|
maxIndex = 3;
|
|
maxVal = m_unusedW;
|
|
}
|
|
|
|
|
|
|
|
|
|
return maxIndex;
|
|
|
|
}
|
|
|
|
|
|
SIMD_FORCE_INLINE int minAxis4() const
|
|
{
|
|
int minIndex = -1;
|
|
float minVal = 1e30f;
|
|
if (m_x < minVal)
|
|
{
|
|
minIndex = 0;
|
|
minVal = m_x;
|
|
}
|
|
if (m_y < minVal)
|
|
{
|
|
minIndex = 1;
|
|
minVal = m_y;
|
|
}
|
|
if (m_z < minVal)
|
|
{
|
|
minIndex = 2;
|
|
minVal = m_z;
|
|
}
|
|
if (m_unusedW < minVal)
|
|
{
|
|
minIndex = 3;
|
|
minVal = m_unusedW;
|
|
}
|
|
|
|
return minIndex;
|
|
|
|
}
|
|
|
|
|
|
SIMD_FORCE_INLINE int closestAxis4() const
|
|
{
|
|
return absolute4().maxAxis4();
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
#endif //SIMD__VECTOR3_H
|