Explorar el Código

math: add GLSL-inherited degrees() and radians() conversion functions.

undefined
Sam Hocevar hace 10 años
padre
commit
8443733a08
Se han modificado 9 ficheros con 122 adiciones y 25 borrados
  1. +2
    -2
      src/camera.cpp
  2. +1
    -1
      src/easymesh/easymesh.cpp
  3. +49
    -0
      src/lol/math/functions.h
  4. +2
    -0
      src/lol/math/half.h
  5. +6
    -0
      src/lol/math/real.h
  6. +18
    -0
      src/lol/math/vector.h
  7. +14
    -0
      src/math/real.cpp
  8. +15
    -22
      src/math/vector.cpp
  9. +15
    -0
      test/unit/trig.cpp

+ 2
- 2
src/camera.cpp Ver fichero

@@ -225,13 +225,13 @@ quat Camera::GetRotation() const
// Calculate the frustum height at a given distance from the camera.
float Camera::GetFrustumHeightAtDistance(float distance, float fov) const
{
return 2.f * distance * lol::tan(fov * .5f * (F_PI / 180.f));
return 2.f * distance * lol::tan(radians(fov * .5f));
}

// Calculate the FOV needed to get a given frustum height at a given distance.
float Camera::GetFOVForHeightAndDistance(float distance, float height) const
{
return 2.f * lol::atan(height * .5f / distance) * (180.f / F_PI);
return 2.f * radians(lol::atan(height * .5f / distance));
}

void Camera::TickGame(float seconds)


+ 1
- 1
src/easymesh/easymesh.cpp Ver fichero

@@ -1450,7 +1450,7 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d)
/* Fill in the icosahedron vertices, rotating them so that there
* is a vertex at [0 1 0] and [0 -1 0] after normalisation. */
float phi = 0.5f + 0.5f * sqrt(5.f);
mat3 mat = mat3::rotate(asin(1.f / sqrt(2.f + phi)) * (180.f / F_PI),
mat3 mat = mat3::rotate(degrees(asin(1.f / sqrt(2.f + phi))),
vec3(0.f, 0.f, 1.f));
for (int i = 0; i < 4; i++)
{


+ 49
- 0
src/lol/math/functions.h Ver fichero

@@ -84,6 +84,55 @@ static inline void sincos(float const &x, float *s, float *c)
*c = std::cos(x);
}

/* Inherited from GLSL */
static inline float degrees(float radians)
{
return radians * (180.0f / F_PI);
}

static inline double degrees(double radians)
{
return radians * (180.0 / D_PI);
}

static inline ldouble degrees(ldouble radians)
{
return radians * (180.0L / LD_PI);
}

static inline int8_t degrees(int8_t x) { return degrees((float)x); }
static inline uint8_t degrees(uint8_t x) { return degrees((float)x); }
static inline int16_t degrees(int16_t x) { return degrees((float)x); }
static inline uint16_t degrees(uint16_t x) { return degrees((float)x); }
static inline int32_t degrees(int32_t x) { return degrees((double)x); }
static inline uint32_t degrees(uint32_t x) { return degrees((double)x); }
static inline int64_t degrees(int64_t x) { return degrees((ldouble)x); }
static inline uint64_t degrees(uint64_t x) { return degrees((ldouble)x); }

static inline float radians(float degrees)
{
return degrees * (F_PI / 180.0f);
}

static inline double radians(double degrees)
{
return degrees * (D_PI / 180.0);
}

static inline ldouble radians(ldouble degrees)
{
return degrees * (LD_PI / 180.0L);
}

static inline int8_t radians(int8_t x) { return radians((float)x); }
static inline uint8_t radians(uint8_t x) { return radians((float)x); }
static inline int16_t radians(int16_t x) { return radians((float)x); }
static inline uint16_t radians(uint16_t x) { return radians((float)x); }
static inline int32_t radians(int32_t x) { return radians((double)x); }
static inline uint32_t radians(uint32_t x) { return radians((double)x); }
static inline int64_t radians(int64_t x) { return radians((ldouble)x); }
static inline uint64_t radians(uint64_t x) { return radians((ldouble)x); }

static inline float lerp(float const &a, float const &b, float const &x)
{
return a + (b - a) * x;


+ 2
- 0
src/lol/math/half.h Ver fichero

@@ -124,6 +124,8 @@ static inline float fmod(half a, half b)
return fmod((float)a, (float)b);
}
static inline float fract(half a) { return fract((float)a); }
static inline float degrees(half a) { return degrees((float)a); }
static inline float radians(half a) { return radians((float)a); }
static inline half abs(half a) { return half::makebits(a.bits & 0x7fffu); }

static inline half clamp(half x, half a, half b)


+ 6
- 0
src/lol/math/real.h Ver fichero

@@ -125,6 +125,8 @@ public:
/* Functions inherited from GLSL */
template<int K> friend Real<K> abs(Real<K> const &x);
template<int K> friend Real<K> fract(Real<K> const &x);
template<int K> friend Real<K> degrees(Real<K> const &x);
template<int K> friend Real<K> radians(Real<K> const &x);

void hexprint() const;
void print(int ndigits = 150) const;
@@ -276,6 +278,8 @@ template<int K> Real<K> round(Real<K> const &x);
template<int K> Real<K> fmod(Real<K> const &x, Real<K> const &y);
template<int K> Real<K> abs(Real<K> const &x);
template<int K> Real<K> fract(Real<K> const &x);
template<int K> Real<K> degrees(Real<K> const &x);
template<int K> Real<K> radians(Real<K> const &x);

template<> real min(real const &a, real const &b);
template<> real max(real const &a, real const &b);
@@ -314,6 +318,8 @@ template<> real round(real const &x);
template<> real fmod(real const &x, real const &y);
template<> real abs(real const &x);
template<> real fract(real const &x);
template<> real degrees(real const &x);
template<> real radians(real const &x);

template<> void real::hexprint() const;
template<> void real::print(int ndigits) const;


+ 18
- 0
src/lol/math/vector.h Ver fichero

@@ -1399,6 +1399,24 @@ extern Quat<T> slerp(Quat<T> const &qa, Quat<T> const &qb, T f);
for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \
ret[n] = lol::abs(a[n]); \
return ret; \
} \
\
tprefix \
inline tname<type> degrees(tname<type> const &a) \
{ \
tname<type> ret; \
for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \
ret[n] = lol::degrees(a[n]); \
return ret; \
} \
\
tprefix \
inline tname<type> radians(tname<type> const &a) \
{ \
tname<type> ret; \
for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \
ret[n] = lol::radians(a[n]); \
return ret; \
}

#define LOL_BINARY_NONVECTOR_FUNS(tname, tprefix, type) \


+ 14
- 0
src/math/real.cpp Ver fichero

@@ -820,6 +820,20 @@ template<> real fract(real const &x)
return x - floor(x);
}

template<> real degrees(real const &x)
{
static real mul = real(180) * real::R_1_PI();

return x * mul;
}

template<> real radians(real const &x)
{
static real mul = real::R_PI() / real(180);

return x * mul;
}

static real fast_log(real const &x)
{
/* This fast log method is tuned to work on the [1..2] range and


+ 15
- 22
src/math/vector.cpp Ver fichero

@@ -352,10 +352,8 @@ template<> mat4 mat4::translate(vec3 v)

template<> mat2 mat2::rotate(float degrees)
{
degrees *= (F_PI / 180.0f);

float st = sin(degrees);
float ct = cos(degrees);
float st = sin(radians(degrees));
float ct = cos(radians(degrees));

mat2 ret;

@@ -370,10 +368,8 @@ template<> mat2 mat2::rotate(float degrees)

template<> mat3 mat3::rotate(float degrees, float x, float y, float z)
{
degrees *= (F_PI / 180.0f);

float st = sin(degrees);
float ct = cos(degrees);
float st = sin(radians(degrees));
float ct = cos(radians(degrees));

float len = std::sqrt(x * x + y * y + z * z);
float invlen = len ? 1.0f / len : 0.0f;
@@ -489,11 +485,11 @@ template<> quat::Quat(mat4 const &m)

template<> quat quat::rotate(float degrees, vec3 const &v)
{
degrees *= (F_PI / 360.0f);
float half_angle = radians(degrees) * 0.5f;

vec3 tmp = normalize(v) * sin(degrees);
vec3 tmp = normalize(v) * sin(half_angle);

return quat(cos(degrees), tmp.x, tmp.y, tmp.z);
return quat(cos(half_angle), tmp.x, tmp.y, tmp.z);
}

template<> quat quat::rotate(float degrees, float x, float y, float z)
@@ -563,17 +559,17 @@ static inline vec3 quat_toeuler_generic(quat const &q, int i, int j, int k)
1.f - 2.f * (sq(q[1 + k]) + sq(q[1 + j])));
}

return (180.0f / F_PI / n) * ret;
return degrees(ret / n);
}

static inline mat3 mat3_fromeuler_generic(vec3 const &v, int i, int j, int k)
{
mat3 ret;

vec3 const radians = (F_PI / 180.0f) * v;
float const s0 = sin(radians[0]), c0 = cos(radians[0]);
float const s1 = sin(radians[1]), c1 = cos(radians[1]);
float const s2 = sin(radians[2]), c2 = cos(radians[2]);
vec3 const w = radians(v);
float const s0 = sin(w[0]), c0 = cos(w[0]);
float const s1 = sin(w[1]), c1 = cos(w[1]);
float const s2 = sin(w[2]), c2 = cos(w[2]);

/* (2 + i - j) % 3 means x-y-z direct order; otherwise indirect */
float const sign = ((2 + i - j) % 3) ? 1.f : -1.f;
@@ -616,7 +612,7 @@ static inline mat3 mat3_fromeuler_generic(vec3 const &v, int i, int j, int k)

static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
{
vec3 const half_angles = (F_PI / 360.0f) * v;
vec3 const half_angles = radians(v * 0.5f);
float const s0 = sin(half_angles[0]), c0 = cos(half_angles[0]);
float const s1 = sin(half_angles[1]), c1 = cos(half_angles[1]);
float const s2 = sin(half_angles[2]), c2 = cos(half_angles[2]);
@@ -771,9 +767,7 @@ template<> mat4 mat4::frustum(float left, float right, float bottom,
template<> mat4 mat4::perspective(float fov_y, float width,
float height, float near, float far)
{
fov_y *= (F_PI / 180.0f);

float t2 = lol::tan(fov_y * 0.5f);
float t2 = lol::tan(radians(fov_y) * 0.5f);
float t1 = t2 * width / height;

return frustum(-near * t1, near * t1, -near * t2, near * t2, near, far);
@@ -783,8 +777,7 @@ template<> mat4 mat4::perspective(float fov_y, float width,
template<> mat4 mat4::shifted_perspective(float fov_y, float screen_size,
float screen_ratio_yx, float near, float far)
{
float new_fov_y = fov_y * (F_PI / 180.0f);
float tan_y = tanf(new_fov_y * .5f);
float tan_y = tanf(radians(fov_y) * .5f);
ASSERT(tan_y > 0.000001f);
float dist_scr = (screen_size * screen_ratio_yx * .5f) / tan_y;



+ 15
- 0
test/unit/trig.cpp Ver fichero

@@ -22,6 +22,21 @@ namespace lol

LOLUNIT_FIXTURE(TrigTest)
{
LOLUNIT_TEST(AngleConversions)
{
LOLUNIT_ASSERT_DOUBLES_EQUAL(D_PI, radians(180.0), 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(D_PI_2, radians(90.0), 1e-5);

LOLUNIT_ASSERT_DOUBLES_EQUAL(F_PI, radians(180.0f), 1e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(F_PI_2, radians(90.0f), 1e-5f);

LOLUNIT_ASSERT_DOUBLES_EQUAL(180.0, degrees(D_PI), 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(90.0, degrees(D_PI_2), 1e-5);

LOLUNIT_ASSERT_DOUBLES_EQUAL(180.0f, degrees(F_PI), 1e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(90.0f, degrees(F_PI_2), 1e-5f);
}

LOLUNIT_TEST(Sin)
{
using std::fabs;


Cargando…
Cancelar
Guardar