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
* instead of calling routines with the hidden "this" parameter. */
inline half() { }
inline half(int f) { *this = makefast(f); }
inline half(float f) { *this = makefast(f); }
inline half(double f) { *this = makefast(f); }

inline int is_nan() const
{
@@ -50,9 +52,12 @@ public:
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 float() const { return tofloat(*this); }

static float tofloat(half h);



+ 100
- 9
src/matrix.cpp View File

@@ -22,6 +22,52 @@ using namespace std;
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,
float d, float e, float f,
float g, float h, float i)
@@ -66,6 +112,21 @@ template<> mat4 mat4::invert() const
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
{
mat4 const &p = *this;
@@ -163,15 +224,6 @@ template<> mat4 mat4::frustum(float left, float right, float bottom,
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)
{
mat4 ret(1.0f);
@@ -181,6 +233,40 @@ template<> mat4 mat4::translate(float x, float y, float z)
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)
{
float st = sinf(theta);
@@ -213,5 +299,10 @@ template<> mat4 mat4::rotate(float theta, float x, float y, float z)
return ret;
}

template<> mat4 mat4::rotate(float theta, vec3 v)
{
return rotate(theta, v.x, v.y, v.z);
}

} /* namespace lol */


+ 50
- 5
src/matrix.h View File

@@ -113,7 +113,14 @@ namespace lol
{ \
using namespace std; \
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) \
inline Vec2<T> e1##e2() const \
@@ -205,8 +212,16 @@ template <typename T> struct Vec2
union { T y; T b; T j; };
};

typedef Vec2<half> f16vec2;
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
@@ -226,6 +241,9 @@ template <typename T> struct Vec3
SWIZZLE333(x); SWIZZLE333(y); SWIZZLE333(z);
SWIZZLE4333(x); SWIZZLE4333(y); SWIZZLE4333(z);

template<typename U>
friend Vec3<U> cross(Vec3<U>, Vec3<U>);

#if !defined __ANDROID__
template<typename U>
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; };
};

typedef Vec3<half> f16vec3;
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
@@ -272,8 +298,16 @@ template <typename T> struct Vec4
union { T w; T d; T l; };
};

typedef Vec4<half> f16vec4;
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) \
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> 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> 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, Vec3<T> v);

void printf() const;

@@ -400,8 +437,16 @@ template <typename T> struct Mat4
Vec4<T> v[4];
};

typedef Mat4<half> f16mat4;
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 */



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

@@ -20,6 +20,56 @@ namespace lol

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
LOLUNIT_TEST(FastMath)
{


Loading…
Cancel
Save