cross product, normalize, etc.legacy
@@ -28,7 +28,9 @@ public: | |||||
/* Constructors. Always inline so that the code can work in registers | /* Constructors. Always inline so that the code can work in registers | ||||
* instead of calling routines with the hidden "this" parameter. */ | * instead of calling routines with the hidden "this" parameter. */ | ||||
inline half() { } | inline half() { } | ||||
inline half(int f) { *this = makefast(f); } | |||||
inline half(float f) { *this = makefast(f); } | inline half(float f) { *this = makefast(f); } | ||||
inline half(double f) { *this = makefast(f); } | |||||
inline int is_nan() const | inline int is_nan() const | ||||
{ | { | ||||
@@ -50,9 +52,12 @@ public: | |||||
return (is_finite() && (bits & 0x7c00u)) || ((bits & 0x7fffu) == 0); | return (is_finite() && (bits & 0x7c00u)) || ((bits & 0x7fffu) == 0); | ||||
} | } | ||||
/* Cast to other types */ | |||||
inline operator float() const { return tofloat(*this); } | |||||
/* Cast to other types -- always inline, see constructors */ | |||||
inline half &operator =(int f) { return *this = makefast(f); } | |||||
inline half &operator =(float f) { return *this = makefast(f); } | |||||
inline half &operator =(double f) { return *this = makefast(f); } | |||||
inline operator int() const { return (int)tofloat(*this); } | inline operator int() const { return (int)tofloat(*this); } | ||||
inline operator float() const { return tofloat(*this); } | |||||
static float tofloat(half h); | static float tofloat(half h); | ||||
@@ -22,6 +22,52 @@ using namespace std; | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
template<> float dot(vec2 v1, vec2 v2) | |||||
{ | |||||
return v1.x * v2.x + v1.y * v2.y; | |||||
} | |||||
template<> float dot(vec3 v1, vec3 v2) | |||||
{ | |||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; | |||||
} | |||||
template<> float dot(vec4 v1, vec4 v2) | |||||
{ | |||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; | |||||
} | |||||
template<> vec3 cross(vec3 v1, vec3 v2) | |||||
{ | |||||
return vec3(v1.y * v2.z - v1.z * v2.y, | |||||
v1.z * v2.x - v1.x * v2.z, | |||||
v1.x * v2.y - v1.y * v2.x); | |||||
} | |||||
template<> vec2 normalize(vec2 v) | |||||
{ | |||||
float norm = v.sqlen(); | |||||
if (!norm) | |||||
return vec2(0); | |||||
return v / norm; | |||||
} | |||||
template<> vec3 normalize(vec3 v) | |||||
{ | |||||
float norm = v.sqlen(); | |||||
if (!norm) | |||||
return vec3(0); | |||||
return v / norm; | |||||
} | |||||
template<> vec4 normalize(vec4 v) | |||||
{ | |||||
float norm = v.sqlen(); | |||||
if (!norm) | |||||
return vec4(0); | |||||
return v / norm; | |||||
} | |||||
static inline float det3(float a, float b, float c, | static inline float det3(float a, float b, float c, | ||||
float d, float e, float f, | float d, float e, float f, | ||||
float g, float h, float i) | float g, float h, float i) | ||||
@@ -66,6 +112,21 @@ template<> mat4 mat4::invert() const | |||||
return ret; | return ret; | ||||
} | } | ||||
template<> void vec2::printf() const | |||||
{ | |||||
Log::Debug("[ %6.6f %6.6f ]\n", x, y); | |||||
} | |||||
template<> void vec3::printf() const | |||||
{ | |||||
Log::Debug("[ %6.6f %6.6f %6.6f ]\n", x, y, z); | |||||
} | |||||
template<> void vec4::printf() const | |||||
{ | |||||
Log::Debug("[ %6.6f %6.6f %6.6f %6.6f ]\n", x, y, z, w); | |||||
} | |||||
template<> void mat4::printf() const | template<> void mat4::printf() const | ||||
{ | { | ||||
mat4 const &p = *this; | mat4 const &p = *this; | ||||
@@ -163,15 +224,6 @@ template<> mat4 mat4::frustum(float left, float right, float bottom, | |||||
return ret; | return ret; | ||||
} | } | ||||
template<> mat4 mat4::perspective(float theta, float width, | |||||
float height, float near, float far) | |||||
{ | |||||
float t1 = tanf(theta / 2.0f); | |||||
float t2 = t1 * height / width; | |||||
return frustum(-near * t1, near * t1, -near * t2, near * t2, near, far); | |||||
} | |||||
template<> mat4 mat4::translate(float x, float y, float z) | template<> mat4 mat4::translate(float x, float y, float z) | ||||
{ | { | ||||
mat4 ret(1.0f); | mat4 ret(1.0f); | ||||
@@ -181,6 +233,40 @@ template<> mat4 mat4::translate(float x, float y, float z) | |||||
return ret; | return ret; | ||||
} | } | ||||
template<> mat4 mat4::translate(vec3 v) | |||||
{ | |||||
return translate(v.x, v.y, v.z); | |||||
} | |||||
template<> mat4 mat4::lookat(vec3 eye, vec3 center, vec3 up) | |||||
{ | |||||
vec3 f = normalize(center - eye); | |||||
vec3 u = normalize(up); | |||||
vec3 s = normalize(cross(f, u)); | |||||
u = cross(s, f); | |||||
mat4 ret(1.0f); | |||||
ret[0][0] = s.x; | |||||
ret[0][1] = s.y; | |||||
ret[0][2] = s.z; | |||||
ret[1][0] = u.x; | |||||
ret[1][1] = u.y; | |||||
ret[1][2] = u.z; | |||||
ret[2][0] =-f.x; | |||||
ret[2][1] =-f.y; | |||||
ret[2][2] =-f.z; | |||||
return ret * mat4::translate(-eye); | |||||
} | |||||
template<> mat4 mat4::perspective(float theta, float width, | |||||
float height, float near, float far) | |||||
{ | |||||
float t1 = tanf(theta * 0.5f); | |||||
float t2 = t1 * height / width; | |||||
return frustum(-near * t1, near * t1, -near * t2, near * t2, near, far); | |||||
} | |||||
template<> mat4 mat4::rotate(float theta, float x, float y, float z) | template<> mat4 mat4::rotate(float theta, float x, float y, float z) | ||||
{ | { | ||||
float st = sinf(theta); | float st = sinf(theta); | ||||
@@ -213,5 +299,10 @@ template<> mat4 mat4::rotate(float theta, float x, float y, float z) | |||||
return ret; | return ret; | ||||
} | } | ||||
template<> mat4 mat4::rotate(float theta, vec3 v) | |||||
{ | |||||
return rotate(theta, v.x, v.y, v.z); | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -113,7 +113,14 @@ namespace lol | |||||
{ \ | { \ | ||||
using namespace std; \ | using namespace std; \ | ||||
return sqrtf((float)sqlen()); \ | return sqrtf((float)sqlen()); \ | ||||
} | |||||
} \ | |||||
\ | |||||
template<typename U> \ | |||||
friend U dot(Vec##elems<U>, Vec##elems<U>); \ | |||||
template<typename U> \ | |||||
friend Vec##elems<U> normalize(Vec##elems<U>); \ | |||||
\ | |||||
void printf() const; | |||||
#define SWIZZLE2(e1, e2) \ | #define SWIZZLE2(e1, e2) \ | ||||
inline Vec2<T> e1##e2() const \ | inline Vec2<T> e1##e2() const \ | ||||
@@ -205,8 +212,16 @@ template <typename T> struct Vec2 | |||||
union { T y; T b; T j; }; | union { T y; T b; T j; }; | ||||
}; | }; | ||||
typedef Vec2<half> f16vec2; | |||||
typedef Vec2<float> vec2; | typedef Vec2<float> vec2; | ||||
typedef Vec2<int> ivec2; | |||||
typedef Vec2<int8_t> i8vec2; | |||||
typedef Vec2<uint8_t> u8vec2; | |||||
typedef Vec2<int16_t> i16vec2; | |||||
typedef Vec2<uint16_t> u16vec2; | |||||
typedef Vec2<int32_t> ivec2; | |||||
typedef Vec2<uint32_t> uvec2; | |||||
typedef Vec2<int64_t> i64vec2; | |||||
typedef Vec2<uint64_t> u64vec2; | |||||
/* | /* | ||||
* 3-element vectors | * 3-element vectors | ||||
@@ -226,6 +241,9 @@ template <typename T> struct Vec3 | |||||
SWIZZLE333(x); SWIZZLE333(y); SWIZZLE333(z); | SWIZZLE333(x); SWIZZLE333(y); SWIZZLE333(z); | ||||
SWIZZLE4333(x); SWIZZLE4333(y); SWIZZLE4333(z); | SWIZZLE4333(x); SWIZZLE4333(y); SWIZZLE4333(z); | ||||
template<typename U> | |||||
friend Vec3<U> cross(Vec3<U>, Vec3<U>); | |||||
#if !defined __ANDROID__ | #if !defined __ANDROID__ | ||||
template<typename U> | template<typename U> | ||||
friend std::ostream &operator<<(std::ostream &stream, Vec3<U> const &v); | friend std::ostream &operator<<(std::ostream &stream, Vec3<U> const &v); | ||||
@@ -236,8 +254,16 @@ template <typename T> struct Vec3 | |||||
union { T z; T c; T k; }; | union { T z; T c; T k; }; | ||||
}; | }; | ||||
typedef Vec3<half> f16vec3; | |||||
typedef Vec3<float> vec3; | typedef Vec3<float> vec3; | ||||
typedef Vec3<int> ivec3; | |||||
typedef Vec3<int8_t> i8vec3; | |||||
typedef Vec3<uint8_t> u8vec3; | |||||
typedef Vec3<int16_t> i16vec3; | |||||
typedef Vec3<uint16_t> u16vec3; | |||||
typedef Vec3<int32_t> ivec3; | |||||
typedef Vec3<uint32_t> uvec3; | |||||
typedef Vec3<int64_t> i64vec3; | |||||
typedef Vec3<uint64_t> u64vec3; | |||||
/* | /* | ||||
* 4-element vectors | * 4-element vectors | ||||
@@ -272,8 +298,16 @@ template <typename T> struct Vec4 | |||||
union { T w; T d; T l; }; | union { T w; T d; T l; }; | ||||
}; | }; | ||||
typedef Vec4<half> f16vec4; | |||||
typedef Vec4<float> vec4; | typedef Vec4<float> vec4; | ||||
typedef Vec4<int> ivec4; | |||||
typedef Vec4<int8_t> i8vec4; | |||||
typedef Vec4<uint8_t> u8vec4; | |||||
typedef Vec4<int16_t> i16vec4; | |||||
typedef Vec4<uint16_t> u16vec4; | |||||
typedef Vec4<int32_t> ivec4; | |||||
typedef Vec4<uint32_t> uvec4; | |||||
typedef Vec4<int64_t> i64vec4; | |||||
typedef Vec4<uint64_t> u64vec4; | |||||
#define SCALAR_GLOBAL(elems, op, U) \ | #define SCALAR_GLOBAL(elems, op, U) \ | ||||
template<typename T> \ | template<typename T> \ | ||||
@@ -326,9 +360,12 @@ template <typename T> struct Mat4 | |||||
static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far); | static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far); | ||||
static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far); | static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far); | ||||
static Mat4<T> lookat(Vec3<T> eye, Vec3<T> center, Vec3<T> up); | |||||
static Mat4<T> perspective(T theta, T width, T height, T near, T far); | static Mat4<T> perspective(T theta, T width, T height, T near, T far); | ||||
static Mat4<T> translate(T x, T y, T z); | static Mat4<T> translate(T x, T y, T z); | ||||
static Mat4<T> translate(Vec3<T> v); | |||||
static Mat4<T> rotate(T theta, T x, T y, T z); | static Mat4<T> rotate(T theta, T x, T y, T z); | ||||
static Mat4<T> rotate(T theta, Vec3<T> v); | |||||
void printf() const; | void printf() const; | ||||
@@ -400,8 +437,16 @@ template <typename T> struct Mat4 | |||||
Vec4<T> v[4]; | Vec4<T> v[4]; | ||||
}; | }; | ||||
typedef Mat4<half> f16mat4; | |||||
typedef Mat4<float> mat4; | typedef Mat4<float> mat4; | ||||
typedef Mat4<int> imat4; | |||||
typedef Mat4<int8_t> i8mat4; | |||||
typedef Mat4<uint8_t> u8mat4; | |||||
typedef Mat4<int16_t> i16mat4; | |||||
typedef Mat4<uint16_t> u16mat4; | |||||
typedef Mat4<int32_t> imat4; | |||||
typedef Mat4<uint32_t> umat4; | |||||
typedef Mat4<int64_t> i64mat4; | |||||
typedef Mat4<uint64_t> u64mat4; | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -20,6 +20,56 @@ namespace lol | |||||
LOLUNIT_FIXTURE(BuildTest) | LOLUNIT_FIXTURE(BuildTest) | ||||
{ | { | ||||
LOLUNIT_TEST(TypeSize) | |||||
{ | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(half), 2); | |||||
//LOLUNIT_ASSERT_EQUAL(sizeof(f16vec2), 4); | |||||
//LOLUNIT_ASSERT_EQUAL(sizeof(f16vec3), 6); | |||||
//LOLUNIT_ASSERT_EQUAL(sizeof(f16vec4), 8); | |||||
//LOLUNIT_ASSERT_EQUAL(sizeof(f16mat4), 32); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(float), 4); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(vec2), 8); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(vec3), 12); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(vec4), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i8vec2), 2); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u8vec2), 2); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i16vec2), 4); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u16vec2), 4); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(ivec2), 8); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(uvec2), 8); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i64vec2), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u64vec2), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i8vec3), 3); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u8vec3), 3); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i16vec3), 6); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u16vec3), 6); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(ivec3), 12); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(uvec3), 12); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i64vec3), 24); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u64vec3), 24); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i8vec4), 4); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u8vec4), 4); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i16vec4), 8); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u16vec4), 8); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(ivec4), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(uvec4), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i64vec4), 32); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u64vec4), 32); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i8mat4), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u8mat4), 16); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i16mat4), 32); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u16mat4), 32); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(imat4), 64); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(umat4), 64); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(i64mat4), 128); | |||||
LOLUNIT_ASSERT_EQUAL(sizeof(u64mat4), 128); | |||||
} | |||||
#if !defined LOL_DEBUG | #if !defined LOL_DEBUG | ||||
LOLUNIT_TEST(FastMath) | LOLUNIT_TEST(FastMath) | ||||
{ | { | ||||