Browse Source

core: new combinations of integer vectors (unsigned, 8-bit, etc.), dot and

cross product, normalize, etc.
legacy
Sam Hocevar sam 13 years ago
parent
commit
4a16c072f2
4 changed files with 207 additions and 16 deletions
  1. +7
    -2
      src/half.h
  2. +100
    -9
      src/matrix.cpp
  3. +50
    -5
      src/matrix.h
  4. +50
    -0
      test/unit/build.cpp

+ 7
- 2
src/half.h View File

@@ -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);




+ 100
- 9
src/matrix.cpp View File

@@ -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 */



+ 50
- 5
src/matrix.h View File

@@ -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 */




+ 50
- 0
test/unit/build.cpp View File

@@ -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)
{ {


Loading…
Cancel
Save