Add the GPU rigid body pipeline from https://github.com/erwincoumans/experiments as a Bullet 3.x preview for Bullet 2.80

This commit is contained in:
erwin.coumans
2012-03-05 00:54:32 +00:00
parent 73c4646b40
commit 571af41cf6
257 changed files with 55106 additions and 0 deletions

View File

@@ -0,0 +1,231 @@
/*
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
#ifndef ARRAY_H
#define ARRAY_H
#include <string.h>
#include <malloc.h>
#include <Common/Base/Error.h>
#include <new.h>
namespace adl
{
template <class T>
class Array
{
public:
__inline
Array();
__inline
Array(int size);
__inline
~Array();
__inline
T& operator[] (int idx);
__inline
const T& operator[] (int idx) const;
__inline
void pushBack(const T& elem);
__inline
void popBack();
__inline
void clear();
__inline
void setSize(int size);
__inline
int getSize() const;
__inline
T* begin();
__inline
const T* begin() const;
__inline
T* end();
__inline
const T* end() const;
__inline
int indexOf(const T& data) const;
__inline
void removeAt(int idx);
__inline
T& expandOne();
private:
Array(const Array& a){}
private:
enum
{
DEFAULT_SIZE = 128,
INCREASE_SIZE = 128,
};
T* m_data;
int m_size;
int m_capacity;
};
template<class T>
Array<T>::Array()
{
m_size = 0;
m_capacity = DEFAULT_SIZE;
// m_data = new T[ m_capacity ];
m_data = (T*)_aligned_malloc(sizeof(T)*m_capacity, 16);
for(int i=0; i<m_capacity; i++) new(&m_data[i])T;
}
template<class T>
Array<T>::Array(int size)
{
m_size = size;
m_capacity = size;
// m_data = new T[ m_capacity ];
m_data = (T*)_aligned_malloc(sizeof(T)*m_capacity, 16);
for(int i=0; i<m_capacity; i++) new(&m_data[i])T;
}
template<class T>
Array<T>::~Array()
{
if( m_data )
{
// delete [] m_data;
_aligned_free( m_data );
m_data = NULL;
}
}
template<class T>
T& Array<T>::operator[](int idx)
{
ADLASSERT(idx<m_size);
return m_data[idx];
}
template<class T>
const T& Array<T>::operator[](int idx) const
{
ADLASSERT(idx<m_size);
return m_data[idx];
}
template<class T>
void Array<T>::pushBack(const T& elem)
{
if( m_size == m_capacity )
{
int oldCap = m_capacity;
m_capacity += INCREASE_SIZE;
// T* s = new T[m_capacity];
T* s = (T*)_aligned_malloc(sizeof(T)*m_capacity, 16);
memcpy( s, m_data, sizeof(T)*oldCap );
// delete [] m_data;
_aligned_free( m_data );
m_data = s;
}
m_data[ m_size++ ] = elem;
}
template<class T>
void Array<T>::popBack()
{
ADLASSERT( m_size>0 );
m_size--;
}
template<class T>
void Array<T>::clear()
{
m_size = 0;
}
template<class T>
void Array<T>::setSize(int size)
{
if( size > m_capacity )
{
int oldCap = m_capacity;
m_capacity = size;
// T* s = new T[m_capacity];
T* s = (T*)_aligned_malloc(sizeof(T)*m_capacity, 16);
for(int i=0; i<m_capacity; i++) new(&s[i])T;
memcpy( s, m_data, sizeof(T)*oldCap );
// delete [] m_data;
_aligned_free( m_data );
m_data = s;
}
m_size = size;
}
template<class T>
int Array<T>::getSize() const
{
return m_size;
}
template<class T>
const T* Array<T>::begin() const
{
return m_data;
}
template<class T>
T* Array<T>::begin()
{
return m_data;
}
template<class T>
T* Array<T>::end()
{
return m_data+m_size;
}
template<class T>
const T* Array<T>::end() const
{
return m_data+m_size;
}
template<class T>
int Array<T>::indexOf(const T& data) const
{
for(int i=0; i<m_size; i++)
{
if( data == m_data[i] ) return i;
}
return -1;
}
template<class T>
void Array<T>::removeAt(int idx)
{
ADLASSERT(idx<m_size);
m_data[idx] = m_data[--m_size];
}
template<class T>
T& Array<T>::expandOne()
{
setSize( m_size+1 );
return m_data[ m_size-1 ];
}
};
#endif

View File

@@ -0,0 +1,173 @@
/*
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
__inline
float2 make_float2(float x, float y)
{
float2 v;
v.s[0] = x; v.s[1] = y;
return v;
}
__inline
float2 make_float2(float x)
{
return make_float2(x,x);
}
__inline
float2 make_float2(const int2& x)
{
return make_float2((float)x.s[0], (float)x.s[1]);
}
__inline
float2 operator-(const float2& a)
{
return make_float2(-a.x, -a.y);
}
__inline
float2 operator*(const float2& a, const float2& b)
{
float2 out;
out.s[0] = a.s[0]*b.s[0];
out.s[1] = a.s[1]*b.s[1];
return out;
}
__inline
float2 operator*(float a, const float2& b)
{
return make_float2(a*b.s[0], a*b.s[1]);
}
__inline
float2 operator*(const float2& b, float a)
{
return make_float2(a*b.s[0], a*b.s[1]);
}
__inline
void operator*=(float2& a, const float2& b)
{
a.s[0]*=b.s[0];
a.s[1]*=b.s[1];
}
__inline
void operator*=(float2& a, float b)
{
a.s[0]*=b;
a.s[1]*=b;
}
__inline
float2 operator/(const float2& a, const float2& b)
{
float2 out;
out.s[0] = a.s[0]/b.s[0];
out.s[1] = a.s[1]/b.s[1];
return out;
}
__inline
float2 operator/(const float2& b, float a)
{
return make_float2(b.s[0]/a, b.s[1]/a);
}
__inline
void operator/=(float2& a, const float2& b)
{
a.s[0]/=b.s[0];
a.s[1]/=b.s[1];
}
__inline
void operator/=(float2& a, float b)
{
a.s[0]/=b;
a.s[1]/=b;
}
//
__inline
float2 operator+(const float2& a, const float2& b)
{
float2 out;
out.s[0] = a.s[0]+b.s[0];
out.s[1] = a.s[1]+b.s[1];
return out;
}
__inline
float2 operator+(const float2& a, float b)
{
float2 out;
out.s[0] = a.s[0]+b;
out.s[1] = a.s[1]+b;
return out;
}
__inline
float2 operator-(const float2& a, const float2& b)
{
float2 out;
out.s[0] = a.s[0]-b.s[0];
out.s[1] = a.s[1]-b.s[1];
return out;
}
__inline
float2 operator-(const float2& a, float b)
{
float2 out;
out.s[0] = a.s[0]-b;
out.s[1] = a.s[1]-b;
return out;
}
__inline
void operator+=(float2& a, const float2& b)
{
a.s[0]+=b.s[0];
a.s[1]+=b.s[1];
}
__inline
void operator+=(float2& a, float b)
{
a.s[0]+=b;
a.s[1]+=b;
}
__inline
void operator-=(float2& a, const float2& b)
{
a.s[0]-=b.s[0];
a.s[1]-=b.s[1];
}
__inline
void operator-=(float2& a, float b)
{
a.s[0]-=b;
a.s[1]-=b;
}

View File

@@ -0,0 +1,375 @@
/*
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) );
}

View File

@@ -0,0 +1,224 @@
/*
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
#ifndef CL_MATH_H
#define CL_MATH_H
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <xmmintrin.h>
#include <Adl/Adl.h>
#include <algorithm>
#define pxSort std::sort
#define PI 3.14159265358979323846f
#define NEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment))
#define _MEM_CLASSALIGN16 __declspec(align(16))
#define _MEM_ALIGNED_ALLOCATOR16 void* operator new(size_t size) { return _aligned_malloc( size, 16 ); } \
void operator delete(void *p) { _aligned_free( p ); } \
void* operator new[](size_t size) { return _aligned_malloc( size, 16 ); } \
void operator delete[](void *p) { _aligned_free( p ); } \
void* operator new(size_t size, void* p) { return p; } \
void operator delete(void *p, void* pp) {}
namespace adl
{
template<class T>
T nextPowerOf2(T n)
{
n -= 1;
for(int i=0; i<sizeof(T)*8; i++)
n = n | (n>>i);
return n+1;
}
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
_MEM_CLASSALIGN16
struct float4
{
_MEM_ALIGNED_ALLOCATOR16;
union
{
struct
{
float x,y,z,w;
};
struct
{
float s[4];
};
__m128 m_quad;
};
};
_MEM_CLASSALIGN16
struct int4
{
_MEM_ALIGNED_ALLOCATOR16;
union
{
struct
{
int x,y,z,w;
};
struct
{
int s[4];
};
};
};
_MEM_CLASSALIGN16
struct uint4
{
_MEM_ALIGNED_ALLOCATOR16;
union
{
struct
{
u32 x,y,z,w;
};
struct
{
u32 s[4];
};
};
};
struct int2
{
union
{
struct
{
int x,y;
};
struct
{
int s[2];
};
};
};
struct float2
{
union
{
struct
{
float x,y;
};
struct
{
float s[2];
};
};
};
template<typename T>
__inline
T max2(const T& a, const T& b)
{
return (a>b)? a:b;
}
template<typename T>
__inline
T min2(const T& a, const T& b)
{
return (a<b)? a:b;
}
#include <AdlPrimitives/Math/Float4.inl>
#include <AdlPrimitives/Math/Float2.inl>
template<typename T>
void swap2(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
__inline
void seedRandom(int seed)
{
srand( seed );
}
template<typename T>
__inline
T getRandom(const T& minV, const T& maxV)
{
float r = (rand()%10000)/10000.f;
T range = maxV - minV;
return (T)(minV + r*range);
}
template<>
__inline
float4 getRandom(const float4& minV, const float4& maxV)
{
float4 r = make_float4( (rand()%10000)/10000.f, (rand()%10000)/10000.f, (rand()%10000)/10000.f, (rand()%10000)/10000.f );
float4 range = maxV - minV;
return (minV + r*range);
}
template<typename T>
T* addByteOffset(void* baseAddr, u32 offset)
{
return (T*)(((u32)baseAddr)+offset);
}
struct Pair32
{
Pair32(){}
Pair32(u32 a, u32 b) : m_a(a), m_b(b){}
u32 m_a;
u32 m_b;
};
struct PtrPair
{
PtrPair(){}
PtrPair(void* a, void* b) : m_a(a), m_b(b){}
template<typename T>
PtrPair(T* a, T* b) : m_a((void*)a), m_b((void*)b){}
void* m_a;
void* m_b;
};
};
#endif

View File

@@ -0,0 +1,357 @@
/*
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
#pragma OPENCL EXTENSION cl_amd_printf : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define GET_GROUP_IDX get_group_id(0)
#define GET_LOCAL_IDX get_local_id(0)
#define GET_GLOBAL_IDX get_global_id(0)
#define GET_GROUP_SIZE get_local_size(0)
#define GET_NUM_GROUPS get_num_groups(0)
#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)
#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)
#define AtomInc(x) atom_inc(&(x))
#define AtomInc1(x, out) out = atom_inc(&(x))
#define AppendInc(x, out) out = atomic_inc(x)
#define AtomAdd(x, value) atom_add(&(x), value)
#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )
#define AtomXhg(x, value) atom_xchg ( &(x), value )
#define SELECT_UINT4( b, a, condition ) select( b,a,condition )
#define make_float4 (float4)
#define make_float2 (float2)
#define make_uint4 (uint4)
#define make_int4 (int4)
#define make_uint2 (uint2)
#define make_int2 (int2)
#define max2 max
#define min2 min
///////////////////////////////////////
// Vector
///////////////////////////////////////
__inline
float fastDiv(float numerator, float denominator)
{
return native_divide(numerator, denominator);
// return numerator/denominator;
}
__inline
float4 fastDiv4(float4 numerator, float4 denominator)
{
return native_divide(numerator, denominator);
}
__inline
float fastSqrtf(float f2)
{
return native_sqrt(f2);
// return sqrt(f2);
}
__inline
float fastRSqrt(float f2)
{
return native_rsqrt(f2);
}
__inline
float fastLength4(float4 v)
{
return fast_length(v);
}
__inline
float4 fastNormalize4(float4 v)
{
return fast_normalize(v);
}
__inline
float sqrtf(float a)
{
// return sqrt(a);
return native_sqrt(a);
}
__inline
float4 cross3(float4 a, float4 b)
{
return cross(a,b);
}
__inline
float dot3F4(float4 a, float4 b)
{
float4 a1 = make_float4(a.xyz,0.f);
float4 b1 = make_float4(b.xyz,0.f);
return dot(a1, b1);
}
__inline
float length3(const float4 a)
{
return sqrtf(dot3F4(a,a));
}
__inline
float dot4(const float4 a, const float4 b)
{
return dot( a, b );
}
// for height
__inline
float dot3w1(const float4 point, const float4 eqn)
{
return dot3F4(point,eqn) + eqn.w;
}
__inline
float4 normalize3(const float4 a)
{
float4 n = make_float4(a.x, a.y, a.z, 0.f);
return fastNormalize4( n );
// 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;
}
///////////////////////////////////////
// Matrix3x3
///////////////////////////////////////
typedef struct
{
float4 m_row[3];
}Matrix3x3;
__inline
Matrix3x3 mtZero();
__inline
Matrix3x3 mtIdentity();
__inline
Matrix3x3 mtTranspose(Matrix3x3 m);
__inline
Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b);
__inline
float4 mtMul1(Matrix3x3 a, float4 b);
__inline
float4 mtMul3(float4 a, Matrix3x3 b);
__inline
Matrix3x3 mtZero()
{
Matrix3x3 m;
m.m_row[0] = (float4)(0.f);
m.m_row[1] = (float4)(0.f);
m.m_row[2] = (float4)(0.f);
return m;
}
__inline
Matrix3x3 mtIdentity()
{
Matrix3x3 m;
m.m_row[0] = (float4)(1,0,0,0);
m.m_row[1] = (float4)(0,1,0,0);
m.m_row[2] = (float4)(0,0,1,0);
return m;
}
__inline
Matrix3x3 mtTranspose(Matrix3x3 m)
{
Matrix3x3 out;
out.m_row[0] = (float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);
out.m_row[1] = (float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);
out.m_row[2] = (float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);
return out;
}
__inline
Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b)
{
Matrix3x3 transB;
transB = mtTranspose( b );
Matrix3x3 ans;
// why this doesn't run when 0ing in the for{}
a.m_row[0].w = 0.f;
a.m_row[1].w = 0.f;
a.m_row[2].w = 0.f;
for(int i=0; i<3; i++)
{
// a.m_row[i].w = 0.f;
ans.m_row[i].x = dot3F4(a.m_row[i],transB.m_row[0]);
ans.m_row[i].y = dot3F4(a.m_row[i],transB.m_row[1]);
ans.m_row[i].z = dot3F4(a.m_row[i],transB.m_row[2]);
ans.m_row[i].w = 0.f;
}
return ans;
}
__inline
float4 mtMul1(Matrix3x3 a, float4 b)
{
float4 ans;
ans.x = dot3F4( a.m_row[0], b );
ans.y = dot3F4( a.m_row[1], b );
ans.z = dot3F4( a.m_row[2], b );
ans.w = 0.f;
return ans;
}
__inline
float4 mtMul3(float4 a, Matrix3x3 b)
{
float4 colx = make_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);
float4 coly = make_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);
float4 colz = make_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);
float4 ans;
ans.x = dot3F4( a, colx );
ans.y = dot3F4( a, coly );
ans.z = dot3F4( a, colz );
return ans;
}
///////////////////////////////////////
// Quaternion
///////////////////////////////////////
typedef float4 Quaternion;
__inline
Quaternion qtMul(Quaternion a, Quaternion b);
__inline
Quaternion qtNormalize(Quaternion in);
__inline
float4 qtRotate(Quaternion q, float4 vec);
__inline
Quaternion qtInvert(Quaternion q);
__inline
Matrix3x3 qtGetRotationMatrix(Quaternion q);
__inline
Quaternion qtMul(Quaternion a, Quaternion b)
{
Quaternion ans;
ans = cross3( a, b );
ans += a.w*b+b.w*a;
// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
ans.w = a.w*b.w - dot3F4(a, b);
return ans;
}
__inline
Quaternion qtNormalize(Quaternion in)
{
return fastNormalize4(in);
// in /= length( in );
// return in;
}
__inline
float4 qtRotate(Quaternion q, float4 vec)
{
Quaternion qInv = qtInvert( q );
float4 vcpy = vec;
vcpy.w = 0.f;
float4 out = qtMul(qtMul(q,vcpy),qInv);
return out;
}
__inline
Quaternion qtInvert(Quaternion q)
{
return (Quaternion)(-q.xyz, q.w);
}
__inline
float4 qtInvRotate(const Quaternion q, float4 vec)
{
return qtRotate( qtInvert( q ), vec );
}
__inline
Matrix3x3 qtGetRotationMatrix(Quaternion quat)
{
float4 quat2 = (float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);
Matrix3x3 out;
out.m_row[0].x=1-2*quat2.y-2*quat2.z;
out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;
out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;
out.m_row[0].w = 0.f;
out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;
out.m_row[1].y=1-2*quat2.x-2*quat2.z;
out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;
out.m_row[1].w = 0.f;
out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;
out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;
out.m_row[2].z=1-2*quat2.x-2*quat2.y;
out.m_row[2].w = 0.f;
return out;
}

View File

@@ -0,0 +1,197 @@
/*
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
#ifndef MATRIX3X3_H
#define MATRIX3X3_H
#include <AdlPrimitives/Math/Math.h>
///////////////////////////////////////
// Matrix3x3
///////////////////////////////////////
namespace adl
{
typedef
_MEM_CLASSALIGN16 struct
{
_MEM_ALIGNED_ALLOCATOR16;
float4 m_row[3];
}Matrix3x3;
__inline
Matrix3x3 mtZero();
__inline
Matrix3x3 mtIdentity();
__inline
Matrix3x3 mtDiagonal(float a, float b, float c);
__inline
Matrix3x3 mtTranspose(const Matrix3x3& m);
__inline
Matrix3x3 mtMul(const Matrix3x3& a, const Matrix3x3& b);
__inline
float4 mtMul1(const Matrix3x3& a, const float4& b);
__inline
Matrix3x3 mtMul2(float a, const Matrix3x3& b);
__inline
float4 mtMul3(const float4& b, const Matrix3x3& a);
__inline
Matrix3x3 mtInvert(const Matrix3x3& m);
__inline
Matrix3x3 mtZero()
{
Matrix3x3 m;
m.m_row[0] = make_float4(0.f);
m.m_row[1] = make_float4(0.f);
m.m_row[2] = make_float4(0.f);
return m;
}
__inline
Matrix3x3 mtIdentity()
{
Matrix3x3 m;
m.m_row[0] = make_float4(1,0,0);
m.m_row[1] = make_float4(0,1,0);
m.m_row[2] = make_float4(0,0,1);
return m;
}
__inline
Matrix3x3 mtDiagonal(float a, float b, float c)
{
Matrix3x3 m;
m.m_row[0] = make_float4(a,0,0);
m.m_row[1] = make_float4(0,b,0);
m.m_row[2] = make_float4(0,0,c);
return m;
}
__inline
Matrix3x3 mtTranspose(const Matrix3x3& m)
{
Matrix3x3 out;
out.m_row[0] = make_float4(m.m_row[0].s[0], m.m_row[1].s[0], m.m_row[2].s[0], 0.f);
out.m_row[1] = make_float4(m.m_row[0].s[1], m.m_row[1].s[1], m.m_row[2].s[1], 0.f);
out.m_row[2] = make_float4(m.m_row[0].s[2], m.m_row[1].s[2], m.m_row[2].s[2], 0.f);
return out;
}
__inline
Matrix3x3 mtMul(const Matrix3x3& a, const Matrix3x3& b)
{
Matrix3x3 transB;
transB = mtTranspose( b );
Matrix3x3 ans;
for(int i=0; i<3; i++)
{
ans.m_row[i].s[0] = dot3F4(a.m_row[i],transB.m_row[0]);
ans.m_row[i].s[1] = dot3F4(a.m_row[i],transB.m_row[1]);
ans.m_row[i].s[2] = dot3F4(a.m_row[i],transB.m_row[2]);
}
return ans;
}
__inline
float4 mtMul1(const Matrix3x3& a, const float4& b)
{
float4 ans;
ans.s[0] = dot3F4( a.m_row[0], b );
ans.s[1] = dot3F4( a.m_row[1], b );
ans.s[2] = dot3F4( a.m_row[2], b );
return ans;
}
__inline
Matrix3x3 mtMul2(float a, const Matrix3x3& b)
{
Matrix3x3 ans;
ans.m_row[0] = a*b.m_row[0];
ans.m_row[1] = a*b.m_row[1];
ans.m_row[2] = a*b.m_row[2];
return ans;
}
__inline
float4 mtMul3(const float4& a, const Matrix3x3& b)
{
float4 ans;
ans.x = a.x*b.m_row[0].x + a.y*b.m_row[1].x + a.z*b.m_row[2].x;
ans.y = a.x*b.m_row[0].y + a.y*b.m_row[1].y + a.z*b.m_row[2].y;
ans.z = a.x*b.m_row[0].z + a.y*b.m_row[1].z + a.z*b.m_row[2].z;
return ans;
}
__inline
Matrix3x3 mtInvert(const Matrix3x3& m)
{
float det = m.m_row[0].s[0]*m.m_row[1].s[1]*m.m_row[2].s[2]+m.m_row[1].s[0]*m.m_row[2].s[1]*m.m_row[0].s[2]+m.m_row[2].s[0]*m.m_row[0].s[1]*m.m_row[1].s[2]
-m.m_row[0].s[0]*m.m_row[2].s[1]*m.m_row[1].s[2]-m.m_row[2].s[0]*m.m_row[1].s[1]*m.m_row[0].s[2]-m.m_row[1].s[0]*m.m_row[0].s[1]*m.m_row[2].s[2];
ADLASSERT( det );
Matrix3x3 ans;
ans.m_row[0].s[0] = m.m_row[1].s[1]*m.m_row[2].s[2] - m.m_row[1].s[2]*m.m_row[2].s[1];
ans.m_row[0].s[1] = m.m_row[0].s[2]*m.m_row[2].s[1] - m.m_row[0].s[1]*m.m_row[2].s[2];
ans.m_row[0].s[2] = m.m_row[0].s[1]*m.m_row[1].s[2] - m.m_row[0].s[2]*m.m_row[1].s[1];
ans.m_row[0].w = 0.f;
ans.m_row[1].s[0] = m.m_row[1].s[2]*m.m_row[2].s[0] - m.m_row[1].s[0]*m.m_row[2].s[2];
ans.m_row[1].s[1] = m.m_row[0].s[0]*m.m_row[2].s[2] - m.m_row[0].s[2]*m.m_row[2].s[0];
ans.m_row[1].s[2] = m.m_row[0].s[2]*m.m_row[1].s[0] - m.m_row[0].s[0]*m.m_row[1].s[2];
ans.m_row[1].w = 0.f;
ans.m_row[2].s[0] = m.m_row[1].s[0]*m.m_row[2].s[1] - m.m_row[1].s[1]*m.m_row[2].s[0];
ans.m_row[2].s[1] = m.m_row[0].s[1]*m.m_row[2].s[0] - m.m_row[0].s[0]*m.m_row[2].s[1];
ans.m_row[2].s[2] = m.m_row[0].s[0]*m.m_row[1].s[1] - m.m_row[0].s[1]*m.m_row[1].s[0];
ans.m_row[2].w = 0.f;
ans = mtMul2((1.0f/det), ans);
return ans;
}
__inline
Matrix3x3 mtSet( const float4& a, const float4& b, const float4& c )
{
Matrix3x3 m;
m.m_row[0] = a;
m.m_row[1] = b;
m.m_row[2] = c;
return m;
}
__inline
Matrix3x3 operator+(const Matrix3x3& a, const Matrix3x3& b)
{
Matrix3x3 out;
out.m_row[0] = a.m_row[0] + b.m_row[0];
out.m_row[1] = a.m_row[1] + b.m_row[1];
out.m_row[2] = a.m_row[2] + b.m_row[2];
return out;
}
};
#endif

View File

@@ -0,0 +1,159 @@
/*
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
#ifndef QUATERNION_H
#define QUATERNION_H
#include <AdlPrimitives/Math/Matrix3x3.h>
namespace adl
{
typedef float4 Quaternion;
__inline
Quaternion qtSet(const float4& axis, float angle);
__inline
Quaternion qtMul(const Quaternion& a, const Quaternion& b);
__inline
float4 qtRotate(const Quaternion& q, const float4& vec);
__inline
float4 qtInvRotate(const Quaternion& q, const float4& vec);
__inline
Quaternion qtInvert(const Quaternion& q);
__inline
Matrix3x3 qtGetRotationMatrix(const Quaternion& quat);
__inline
Quaternion qtNormalize(const Quaternion& q);
__inline
Quaternion qtGetIdentity() { return make_float4(0,0,0,1); }
__inline
Quaternion qtSet(const float4& axis, float angle)
{
float4 nAxis = normalize3( axis );
Quaternion q;
q.s[0] = nAxis.s[0]*sin(angle/2);
q.s[1] = nAxis.s[1]*sin(angle/2);
q.s[2] = nAxis.s[2]*sin(angle/2);
q.s[3] = cos(angle/2);
return q;
}
__inline
Quaternion qtMul(const Quaternion& a, const Quaternion& b)
{
Quaternion ans;
ans = cross3( a, b );
ans += a.s[3]*b + b.s[3]*a;
ans.s[3] = a.s[3]*b.s[3] - (a.s[0]*b.s[0]+a.s[1]*b.s[1]+a.s[2]*b.s[2]);
return ans;
}
__inline
float4 qtRotate(const Quaternion& q, const float4& vec)
{
Quaternion vecQ = vec;
vecQ.s[3] = 0.f;
Quaternion qInv = qtInvert( q );
float4 out = qtMul(qtMul(q,vecQ),qInv);
return out;
}
__inline
float4 qtInvRotate(const Quaternion& q, const float4& vec)
{
return qtRotate( qtInvert( q ), vec );
}
__inline
Quaternion qtInvert(const Quaternion& q)
{
Quaternion ans;
ans.s[0] = -q.s[0];
ans.s[1] = -q.s[1];
ans.s[2] = -q.s[2];
ans.s[3] = q.s[3];
return ans;
}
__inline
Matrix3x3 qtGetRotationMatrix(const Quaternion& quat)
{
float4 quat2 = make_float4(quat.s[0]*quat.s[0], quat.s[1]*quat.s[1], quat.s[2]*quat.s[2], 0.f);
Matrix3x3 out;
out.m_row[0].s[0]=1-2*quat2.s[1]-2*quat2.s[2];
out.m_row[0].s[1]=2*quat.s[0]*quat.s[1]-2*quat.s[3]*quat.s[2];
out.m_row[0].s[2]=2*quat.s[0]*quat.s[2]+2*quat.s[3]*quat.s[1];
out.m_row[0].s[3] = 0.f;
out.m_row[1].s[0]=2*quat.s[0]*quat.s[1]+2*quat.s[3]*quat.s[2];
out.m_row[1].s[1]=1-2*quat2.s[0]-2*quat2.s[2];
out.m_row[1].s[2]=2*quat.s[1]*quat.s[2]-2*quat.s[3]*quat.s[0];
out.m_row[1].s[3] = 0.f;
out.m_row[2].s[0]=2*quat.s[0]*quat.s[2]-2*quat.s[3]*quat.s[1];
out.m_row[2].s[1]=2*quat.s[1]*quat.s[2]+2*quat.s[3]*quat.s[0];
out.m_row[2].s[2]=1-2*quat2.s[0]-2*quat2.s[1];
out.m_row[2].s[3] = 0.f;
return out;
}
__inline
Quaternion qtGetQuaternion(const Matrix3x3* m)
{
Quaternion q;
q.w = sqrtf( m[0].m_row[0].x + m[0].m_row[1].y + m[0].m_row[2].z + 1 ) * 0.5f;
float inv4w = 1.f/(4.f*q.w);
q.x = (m[0].m_row[2].y-m[0].m_row[1].z)*inv4w;
q.y = (m[0].m_row[0].z-m[0].m_row[2].x)*inv4w;
q.z = (m[0].m_row[1].x-m[0].m_row[0].y)*inv4w;
return q;
}
__inline
Quaternion qtNormalize(const Quaternion& q)
{
return normalize4(q);
}
__inline
float4 transform(const float4& p, const float4& translation, const Quaternion& orientation)
{
return qtRotate( orientation, p ) + translation;
}
__inline
float4 invTransform(const float4& p, const float4& translation, const Quaternion& orientation)
{
return qtRotate( qtInvert( orientation ), p-translation ); // use qtInvRotate
}
};
#endif