376 lines
6.4 KiB
C++
376 lines
6.4 KiB
C++
/*
|
|
Copyright (c) 2012 Advanced Micro Devices, Inc.
|
|
|
|
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.
|
|
*/
|
|
//Originally written by Takahiro Harada
|
|
|
|
|
|
//#define CHECK_ALIGNMENT(a) ADLASSERT((u32(&(a)) & 0xf) == 0);
|
|
#define CHECK_ALIGNMENT(a) a;
|
|
|
|
|
|
__inline
|
|
float4 make_float4(float x, float y, float z, float w = 0.f)
|
|
{
|
|
float4 v;
|
|
v.x = x; v.y = y; v.z = z; v.w = w;
|
|
return v;
|
|
}
|
|
|
|
__inline
|
|
float4 make_float4(float x)
|
|
{
|
|
return make_float4(x,x,x,x);
|
|
}
|
|
|
|
__inline
|
|
float4 make_float4(const int4& x)
|
|
{
|
|
return make_float4((float)x.s[0], (float)x.s[1], (float)x.s[2], (float)x.s[3]);
|
|
}
|
|
|
|
__inline
|
|
int4 make_int4(int x, int y, int z, int w = 0)
|
|
{
|
|
int4 v;
|
|
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
|
|
return v;
|
|
}
|
|
|
|
__inline
|
|
int4 make_int4(int x)
|
|
{
|
|
return make_int4(x,x,x,x);
|
|
}
|
|
|
|
__inline
|
|
int4 make_int4(const float4& x)
|
|
{
|
|
return make_int4((int)x.x, (int)x.y, (int)x.z, (int)x.w);
|
|
}
|
|
|
|
__inline
|
|
int2 make_int2(int a, int b)
|
|
{
|
|
int2 ans; ans.x = a; ans.y = b;
|
|
return ans;
|
|
}
|
|
|
|
__inline
|
|
bool operator ==(const int2& a, const int2& b)
|
|
{
|
|
return a.x==b.x && a.y==b.y;
|
|
}
|
|
|
|
__inline
|
|
bool operator ==(const int4& a, const int4& b)
|
|
{
|
|
return a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w;
|
|
}
|
|
|
|
__inline
|
|
bool operator ==(const float2& a, const float2& b)
|
|
{
|
|
return a.x==b.x && a.y==b.y;
|
|
}
|
|
|
|
__inline
|
|
bool operator ==(const float4& a, const float4& b)
|
|
{
|
|
return a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w;
|
|
}
|
|
|
|
__inline
|
|
float4 operator-(const float4& a)
|
|
{
|
|
return make_float4(-a.x, -a.y, -a.z, -a.w);
|
|
}
|
|
|
|
__inline
|
|
float4 operator*(const float4& a, const float4& b)
|
|
{
|
|
// ADLASSERT((u32(&a) & 0xf) == 0);
|
|
|
|
float4 out;
|
|
out.s[0] = a.s[0]*b.s[0];
|
|
out.s[1] = a.s[1]*b.s[1];
|
|
out.s[2] = a.s[2]*b.s[2];
|
|
out.s[3] = a.s[3]*b.s[3];
|
|
return out;
|
|
}
|
|
|
|
__inline
|
|
float4 operator*(float a, const float4& b)
|
|
{
|
|
return make_float4(a*b.s[0], a*b.s[1], a*b.s[2], a*b.s[3]);
|
|
}
|
|
|
|
__inline
|
|
float4 operator*(const float4& b, float a)
|
|
{
|
|
CHECK_ALIGNMENT(b);
|
|
|
|
return make_float4(a*b.s[0], a*b.s[1], a*b.s[2], a*b.s[3]);
|
|
}
|
|
|
|
__inline
|
|
void operator*=(float4& a, const float4& b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
a.s[0]*=b.s[0];
|
|
a.s[1]*=b.s[1];
|
|
a.s[2]*=b.s[2];
|
|
a.s[3]*=b.s[3];
|
|
}
|
|
|
|
__inline
|
|
void operator*=(float4& a, float b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
a.s[0]*=b;
|
|
a.s[1]*=b;
|
|
a.s[2]*=b;
|
|
a.s[3]*=b;
|
|
}
|
|
/*
|
|
__inline
|
|
bool operator ==(const float4& a, const float4& b)
|
|
{
|
|
|
|
|
|
}
|
|
*/
|
|
//
|
|
__inline
|
|
float4 operator/(const float4& a, const float4& b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
float4 out;
|
|
out.s[0] = a.s[0]/b.s[0];
|
|
out.s[1] = a.s[1]/b.s[1];
|
|
out.s[2] = a.s[2]/b.s[2];
|
|
out.s[3] = a.s[3]/b.s[3];
|
|
return out;
|
|
}
|
|
|
|
__inline
|
|
float4 operator/(const float4& b, float a)
|
|
{
|
|
CHECK_ALIGNMENT(b);
|
|
|
|
return make_float4(b.s[0]/a, b.s[1]/a, b.s[2]/a, b.s[3]/a);
|
|
}
|
|
|
|
__inline
|
|
void operator/=(float4& a, const float4& b)
|
|
{
|
|
a.s[0]/=b.s[0];
|
|
a.s[1]/=b.s[1];
|
|
a.s[2]/=b.s[2];
|
|
a.s[3]/=b.s[3];
|
|
}
|
|
|
|
__inline
|
|
void operator/=(float4& a, float b)
|
|
{
|
|
ADLASSERT((u32(&a) & 0xf) == 0);
|
|
|
|
a.s[0]/=b;
|
|
a.s[1]/=b;
|
|
a.s[2]/=b;
|
|
a.s[3]/=b;
|
|
}
|
|
//
|
|
|
|
__inline
|
|
float4 operator+(const float4& a, const float4& b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
float4 out;
|
|
out.s[0] = a.s[0]+b.s[0];
|
|
out.s[1] = a.s[1]+b.s[1];
|
|
out.s[2] = a.s[2]+b.s[2];
|
|
out.s[3] = a.s[3]+b.s[3];
|
|
return out;
|
|
}
|
|
|
|
__inline
|
|
float4 operator+(const float4& a, float b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
float4 out;
|
|
out.s[0] = a.s[0]+b;
|
|
out.s[1] = a.s[1]+b;
|
|
out.s[2] = a.s[2]+b;
|
|
out.s[3] = a.s[3]+b;
|
|
return out;
|
|
}
|
|
|
|
__inline
|
|
float4 operator-(const float4& a, const float4& b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
float4 out;
|
|
out.s[0] = a.s[0]-b.s[0];
|
|
out.s[1] = a.s[1]-b.s[1];
|
|
out.s[2] = a.s[2]-b.s[2];
|
|
out.s[3] = a.s[3]-b.s[3];
|
|
return out;
|
|
}
|
|
|
|
__inline
|
|
float4 operator-(const float4& a, float b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
float4 out;
|
|
out.s[0] = a.s[0]-b;
|
|
out.s[1] = a.s[1]-b;
|
|
out.s[2] = a.s[2]-b;
|
|
out.s[3] = a.s[3]-b;
|
|
return out;
|
|
}
|
|
|
|
__inline
|
|
void operator+=(float4& a, const float4& b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
a.s[0]+=b.s[0];
|
|
a.s[1]+=b.s[1];
|
|
a.s[2]+=b.s[2];
|
|
a.s[3]+=b.s[3];
|
|
}
|
|
|
|
__inline
|
|
void operator+=(float4& a, float b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
a.s[0]+=b;
|
|
a.s[1]+=b;
|
|
a.s[2]+=b;
|
|
a.s[3]+=b;
|
|
}
|
|
|
|
__inline
|
|
void operator-=(float4& a, const float4& b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
a.s[0]-=b.s[0];
|
|
a.s[1]-=b.s[1];
|
|
a.s[2]-=b.s[2];
|
|
a.s[3]-=b.s[3];
|
|
}
|
|
|
|
__inline
|
|
void operator-=(float4& a, float b)
|
|
{
|
|
CHECK_ALIGNMENT(a);
|
|
|
|
a.s[0]-=b;
|
|
a.s[1]-=b;
|
|
a.s[2]-=b;
|
|
a.s[3]-=b;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
__inline
|
|
float4 cross3(const float4& a, const float4& b)
|
|
{
|
|
return make_float4(a.s[1]*b.s[2]-a.s[2]*b.s[1],
|
|
a.s[2]*b.s[0]-a.s[0]*b.s[2],
|
|
a.s[0]*b.s[1]-a.s[1]*b.s[0],
|
|
0);
|
|
}
|
|
|
|
__inline
|
|
float dot3F4(const float4& a, const float4& b)
|
|
{
|
|
return a.x*b.x+a.y*b.y+a.z*b.z;
|
|
}
|
|
|
|
__inline
|
|
float length3(const float4& a)
|
|
{
|
|
return sqrtf(dot3F4(a,a));
|
|
}
|
|
|
|
__inline
|
|
float dot4(const float4& a, const float4& b)
|
|
{
|
|
return a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w;
|
|
}
|
|
|
|
// for height
|
|
__inline
|
|
float dot3w1(const float4& point, const float4& eqn)
|
|
{
|
|
return point.x*eqn.x+point.y*eqn.y+point.z*eqn.z+eqn.w;
|
|
}
|
|
|
|
__inline
|
|
float4 normalize3(const float4& a)
|
|
{
|
|
float length = sqrtf(dot3F4(a, a));
|
|
return 1.f/length * a;
|
|
}
|
|
|
|
__inline
|
|
float4 normalize4(const float4& a)
|
|
{
|
|
float length = sqrtf(dot4(a, a));
|
|
return 1.f/length * a;
|
|
}
|
|
|
|
__inline
|
|
float4 createEquation(const float4& a, const float4& b, const float4& c)
|
|
{
|
|
float4 eqn;
|
|
float4 ab = b-a;
|
|
float4 ac = c-a;
|
|
eqn = normalize3( cross3(ab, ac) );
|
|
eqn.w = -dot3F4(eqn,a);
|
|
return eqn;
|
|
}
|
|
|
|
__inline
|
|
float intersectPlaneLine( const float4& planeEqn, const float4& vec, const float4& orig )
|
|
{
|
|
return (-planeEqn.w - dot3F4(planeEqn, orig))/dot3F4(planeEqn, vec);
|
|
}
|
|
|
|
template<>
|
|
__inline
|
|
float4 max2(const float4& a, const float4& b)
|
|
{
|
|
return make_float4( max2(a.x,b.x), max2(a.y,b.y), max2(a.z,b.z), max2(a.w,b.w) );
|
|
}
|
|
|
|
template<>
|
|
__inline
|
|
float4 min2(const float4& a, const float4& b)
|
|
{
|
|
return make_float4( min2(a.x,b.x), min2(a.y,b.y), min2(a.z,b.z), min2(a.w,b.w) );
|
|
}
|
|
|