Przeglądaj źródła

Improve standalone inclusion support.

wip/core-clipp
Sam Hocevar 4 lat temu
rodzic
commit
d05eb96665
15 zmienionych plików z 363 dodań i 280 usunięć
  1. +5
    -4
      include/lol/base/lolunit.h
  2. +3
    -1
      include/lol/image/color.h
  3. +6
    -2
      include/lol/math/polynomial.h
  4. +1
    -17
      include/lol/math/private/matrix.h
  5. +10
    -5
      include/lol/math/private/matrix.ipp
  6. +7
    -0
      include/lol/math/private/ops.h
  7. +31
    -15
      include/lol/math/private/transform.ipp
  8. +2
    -0
      include/lol/math/private/vector.ipp
  9. +105
    -12
      include/lol/math/transform.h
  10. +125
    -44
      include/lol/math/vector.h
  11. +8
    -5
      include/lol/types/half.h
  12. +0
    -128
      legacy/lol/base/types.h
  13. +28
    -26
      legacy/lol/math/geometry.h
  14. +9
    -5
      legacy/lol/math/noise/gradient.h
  15. +23
    -16
      legacy/lol/math/noise/simplex.h

+ 5
- 4
include/lol/base/lolunit.h Wyświetl plik

@@ -17,10 +17,11 @@
// ———————————————————————
//

#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <iostream> // std::cout
#include <iomanip> // std::setprecision
#include <sstream> // std::stringstream
#include <string> // std::string
#include <cmath> // std::fabs

namespace lol
{


+ 3
- 1
include/lol/image/color.h Wyświetl plik

@@ -18,7 +18,9 @@
// Provides various color conversion routines.
//

#include <lol/math/vector.h>
#include <../legacy/lol/math/functions.h> // FIXME: try to remove this
#include <lol/math/vector.h> // vec_t
#include <lol/math/transform.h> // mat_t

namespace lol
{


+ 6
- 2
include/lol/math/polynomial.h Wyświetl plik

@@ -25,6 +25,7 @@
#include <functional> // std::function
#include <tuple> // std::tuple
#include <cassert> // assert()
#include <cmath> // sqrt(), cbrt(), acos()

namespace lol
{
@@ -114,6 +115,9 @@ struct [[nodiscard]] polynomial

std::vector<T> roots() const
{
using std::cos, std::acos, std::atan2;
using std::sqrt, std::cbrt, std::fabs;

/* For now we can only solve polynomials of degrees 0, 1, 2 or 3. */
assert(degree() >= 0 && degree() <= 3);

@@ -212,8 +216,8 @@ struct [[nodiscard]] polynomial
{
T const sqrt_delta = sqrt(delta);

u_norm = cbrt(abs(n - sqrt_delta) / T(2));
v_norm = cbrt(abs(n + sqrt_delta) / T(2));
u_norm = cbrt(fabs(n - sqrt_delta) / T(2));
v_norm = cbrt(fabs(n + sqrt_delta) / T(2));

u3_angle = (n >= sqrt_delta) ? pi : 0;
v3_angle = (n <= -sqrt_delta) ? 0 : -pi;


+ 1
- 17
include/lol/math/private/matrix.h Wyświetl plik

@@ -117,10 +117,6 @@ private:
vec_t<T,2> m_data[2];
};

static_assert(sizeof(imat2) == 16, "sizeof(imat2) == 16");
static_assert(sizeof(mat2) == 16, "sizeof(mat2) == 16");
static_assert(sizeof(dmat2) == 32, "sizeof(dmat2) == 32");

/*
* 3×3-element matrices
*/
@@ -207,10 +203,6 @@ private:
vec_t<T,3> m_data[3];
};

static_assert(sizeof(imat3) == 36, "sizeof(imat3) == 36");
static_assert(sizeof(mat3) == 36, "sizeof(mat3) == 36");
static_assert(sizeof(dmat3) == 72, "sizeof(dmat3) == 72");

/*
* 4×4-element matrices
*/
@@ -340,10 +332,6 @@ private:
vec_t<T,4> m_data[4];
};

static_assert(sizeof(imat4) == 64, "sizeof(imat4) == 64");
static_assert(sizeof(mat4) == 64, "sizeof(mat4) == 64");
static_assert(sizeof(dmat4) == 128, "sizeof(dmat4) == 128");

/*
* stdstream method implementations
*/
@@ -383,8 +371,6 @@ static inline mat_t<T, ROWS, COLS> transpose(mat_t<T, COLS, ROWS> const &m)
template<typename T, int N>
mat_t<T, N - 1, N - 1> submatrix(mat_t<T, N, N> const &m, int i, int j)
{
ASSERT(i >= 0); ASSERT(j >= 0); ASSERT(i < N); ASSERT(j < N);

mat_t<T, N - 1, N - 1> ret;
for (int i2 = 0; i2 < N - 1; ++i2)
for (int j2 = 0; j2 < N - 1; ++j2)
@@ -400,7 +386,6 @@ mat_t<T, N - 1, N - 1> submatrix(mat_t<T, N, N> const &m, int i, int j)
template<typename T, int N> [[nodiscard]]
T cofactor(mat_t<T, N, N> const &m, int i, int j)
{
ASSERT(i >= 0); ASSERT(j >= 0); ASSERT(i < N); ASSERT(j < N);
T tmp = determinant(submatrix(m, i, j));
return ((i + j) & 1) ? -tmp : tmp;
}
@@ -409,7 +394,6 @@ template<typename T> [[nodiscard]]
T cofactor(mat_t<T, 2, 2> const &m, int i, int j)
{
/* This specialisation shouldn't be needed, but Visual Studio. */
ASSERT(i >= 0); ASSERT(j >= 0); ASSERT(i < 2); ASSERT(j < 2);
T tmp = m[1 - i][1 - j];
return (i ^ j) ? -tmp : tmp;
}
@@ -430,7 +414,7 @@ std::tuple<mat_t<T, N, N>, vec_t<int, N>, int> lu_decomposition(mat_t<T, N, N> c
// Find row with the largest absolute value
int best_j = k;
for (int j = k + 1; j < N; ++j)
if (abs(lu[k][j]) > lol::abs(lu[k][best_j]))
if (fabs(lu[k][j]) > fabs(lu[k][best_j]))
best_j = j;

// Swap rows in result


+ 10
- 5
include/lol/math/private/matrix.ipp Wyświetl plik

@@ -13,7 +13,8 @@
#pragma once

#include <cassert>
#include <cmath>
#include <cmath> // std::tan
#include <algorithm> // std::max

#if _WIN32
# pragma push_macro("near")
@@ -256,7 +257,9 @@ template<>
inline mat4 mat4::perspective(float fov_y, float width,
float height, float near, float far)
{
float t2 = lol::tan(fov_y * 0.5f);
using std::tan;

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

return frustum(-near * t1, near * t1, -near * t2, near * t2, near, far);
@@ -272,13 +275,15 @@ inline mat4 mat4::shifted_perspective(float fov_y, float screen_size,
float screen_ratio_yx,
float near, float far)
{
float tan_y = tanf(fov_y * .5f);
using std::tan;

float tan_y = tan(fov_y * .5f);
assert(tan_y > 0.000001f);
float dist_scr = (screen_size * screen_ratio_yx * .5f) / tan_y;

return mat4::perspective(fov_y, screen_size, screen_size * screen_ratio_yx,
max(.001f, dist_scr + near),
max(.001f, dist_scr + far)) *
std::max(.001f, dist_scr + near),
std::max(.001f, dist_scr + far)) *
mat4::translate(.0f, .0f, -dist_scr);
}



+ 7
- 0
include/lol/math/private/ops.h Wyświetl plik

@@ -20,9 +20,16 @@
#include <ostream>
#include <type_traits>

// HACK: if this is declared int const, Visual Studio becomes unable
// to perform template argument deduction.
// FIXME: should we get rid of this #define?
#define FULL_SWIZZLE (0)

namespace lol
{

template<typename T, int N, int SWIZZLE = FULL_SWIZZLE> struct vec_t;

/*
* Utility namespaces for traits -- this file uses a combination of
* ADL black magic and enable_if to ensure that only the expected type


+ 31
- 15
include/lol/math/private/transform.ipp Wyświetl plik

@@ -12,6 +12,8 @@

#pragma once

#include <cmath> // std::cos, std::sin

namespace lol
{

@@ -31,10 +33,10 @@ inline std::string quat::tostring() const
template<>
inline quat quat::rotate(float radians, vec3 const &v)
{
float half_angle = radians * 0.5f;
using std::sin, std::cos;

float half_angle = radians * 0.5f;
vec3 tmp = normalize(v) * sin(half_angle);

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

@@ -47,10 +49,12 @@ inline quat quat::rotate(float radians, float x, float y, float z)
template<>
inline quat quat::rotate(vec3 const &src, vec3 const &dst)
{
using std::sqrt;

/* Algorithm directly taken from Sam Hocevar's article "Quaternion from
* two vectors: the final version".
* http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final */
float magnitude = lol::sqrt(sqlength(src) * sqlength(dst));
float magnitude = sqrt(sqlength(src) * sqlength(dst));
float real_part = magnitude + dot(src, dst);
vec3 w;

@@ -60,8 +64,7 @@ inline quat quat::rotate(vec3 const &src, vec3 const &dst)
* around an arbitrary orthogonal axis. Axis normalisation
* can happen later, when we normalise the quaternion. */
real_part = 0.0f;
w = abs(src.x) > abs(src.z) ? vec3(-src.y, src.x, 0.f)
: vec3(0.f, -src.z, src.y);
w = orthogonal(src);
}
else
{
@@ -75,8 +78,10 @@ inline quat quat::rotate(vec3 const &src, vec3 const &dst)
template<>
inline quat slerp(quat const &qa, quat const &qb, float f)
{
float const magnitude = lol::sqrt(sqlength(qa) * sqlength(qb));
float const product = lol::dot(qa, qb) / magnitude;
using std::sin, std::cos, std::sqrt, std::acos;

float const magnitude = sqrt(sqlength(qa) * sqlength(qb));
float const product = dot(qa, qb) / magnitude;

/* If quaternions are equal or opposite, there is no need
* to slerp anything, just return qa. */
@@ -84,18 +89,25 @@ inline quat slerp(quat const &qa, quat const &qb, float f)
return qa;

float const sign = (product < 0.0f) ? -1.0f : 1.0f;
float const theta = lol::acos(sign * product);
float const s1 = lol::sin(sign * f * theta);
float const s0 = lol::sin((1.0f - f) * theta);
float const theta = acos(sign * product);
float const s1 = sin(sign * f * theta);
float const s0 = sin((1.0f - f) * theta);

/* This is the same as 1/sin(theta) */
float const d = 1.0f / lol::sqrt(1.f - product * product);
float const d = 1.0f / sqrt(1.f - product * product);

return qa * (s0 * d) + qb * (s1 * d);
}

static inline float sq(float x)
{
return x * x;
}

static inline vec3 quat_toeuler_generic(quat const &q, int i, int j, int k)
{
using std::atan2, std::acos, std::asin;

float n = norm(q);

if (!n)
@@ -132,6 +144,8 @@ static inline vec3 quat_toeuler_generic(quat const &q, int i, int j, int k)

static inline mat3 mat3_fromeuler_generic(vec3 const &v, int i, int j, int k)
{
using std::sin, std::cos;

mat3 ret;

float const s0 = sin(v[0]), c0 = cos(v[0]);
@@ -179,6 +193,8 @@ 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)
{
using std::sin, std::cos;

vec3 const half_angles = 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]);
@@ -218,7 +234,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
/* Create quaternions from Euler angles */ \
template<> inline quat quat::fromeuler_##name(vec3 const &v) \
{ \
int x = 0, y = 1, z = 2; UNUSED(x, y, z); \
int x = 0, y = 1, z = 2; (void)x, (void)y, (void)z; \
return quat_fromeuler_generic(v, a1, a2, a3); \
} \
\
@@ -230,7 +246,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
/* Create 3×3 matrices from Euler angles */ \
template<> inline mat3 mat3::fromeuler_##name(vec3 const &v) \
{ \
int x = 0, y = 1, z = 2; UNUSED(x, y, z); \
int x = 0, y = 1, z = 2; (void)x, (void)y, (void)z; \
return mat3_fromeuler_generic(v, a1, a2, a3); \
} \
\
@@ -242,7 +258,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
/* Create 4×4 matrices from Euler angles */ \
template<> inline mat4 mat4::fromeuler_##name(vec3 const &v) \
{ \
int x = 0, y = 1, z = 2; UNUSED(x, y, z); \
int x = 0, y = 1, z = 2; (void)x, (void)y, (void)z; \
return mat4(mat3_fromeuler_generic(v, a1, a2, a3), 1.f); \
} \
\
@@ -254,7 +270,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
/* Retrieve Euler angles from a quaternion */ \
template<> inline vec3 vec3::toeuler_##name(quat const &q) \
{ \
int x = 0, y = 1, z = 2; UNUSED(x, y, z); \
int x = 0, y = 1, z = 2; (void)x, (void)y, (void)z; \
return quat_toeuler_generic(q, a1, a2, a3); \
}



+ 2
- 0
include/lol/math/private/vector.ipp Wyświetl plik

@@ -12,6 +12,8 @@

#pragma once

#include <lol/base/private/string.h> // lol::format

namespace lol
{



+ 105
- 12
include/lol/math/transform.h Wyświetl plik

@@ -20,7 +20,8 @@
#include <lol/math/private/ops.h>
#include <lol/math/vector.h>

#include <ostream>
#include <ostream> // std::ostream
#include <cmath> // std::atan2, std::sqrt

#include "private/matrix.h"

@@ -71,9 +72,6 @@ struct [[nodiscard]] cmplx_t : public linear_ops::base<T>
T x, y;
};

static_assert(sizeof(cmplx) == 8, "sizeof(cmplx) == 8");
static_assert(sizeof(dcmplx) == 16, "sizeof(dcmplx) == 16");

/*
* 4-element transforms: quaternions
*/
@@ -104,11 +102,13 @@ struct [[nodiscard]] quat_t : public linear_ops::base<T>
/* Construct a unit quaternion from a pure rotation matrix */
explicit quat_t(mat_t<T,3,3> const &m)
{
using std::sqrt;

T tr = m[0][0] + m[1][1] + m[2][2];

if (tr > T(0))
{
T const p = T(0.5) * std::sqrt(T(1) + tr);
T const p = T(0.5) * sqrt(T(1) + tr);
T const q = T(0.25) / p;

w = p;
@@ -123,7 +123,7 @@ struct [[nodiscard]] quat_t : public linear_ops::base<T>
: 2;
int j = (i + 1) % 3, k = (i + 2) % 3;

T const p = T(0.5) * lol::sqrt(T(1) - tr + m[i][i] + m[i][i]);
T const p = T(0.5) * sqrt(T(1) - tr + m[i][i] + m[i][i]);
T const q = T(0.25) / p;

w = q * (m[j][k] - m[k][j]);
@@ -235,11 +235,13 @@ struct [[nodiscard]] quat_t : public linear_ops::base<T>

[[nodiscard]] inline T angle()
{
using std::atan2, std::sqrt;

vec_t<T,3> v(x, y, z);
T n2 = sqlength(v);
if (n2 <= (T)1e-6)
return (T)0;
return (T)2 * lol::atan2(lol::sqrt(n2), w);
return (T)2 * atan2(sqrt(n2), w);
}

template<typename U>
@@ -249,9 +251,6 @@ struct [[nodiscard]] quat_t : public linear_ops::base<T>
T w, x, y, z;
};

static_assert(sizeof(quat) == 16, "sizeof(quat) == 16");
static_assert(sizeof(dquat) == 32, "sizeof(dquat) == 32");

/*
* SQT transforms: scale / rotation / translation
*/
@@ -359,6 +358,7 @@ static inline T sqlength(cmplx_t<T> const &t)
template<typename T> [[nodiscard]]
static inline T length(cmplx_t<T> const &t)
{
using std::sqrt;
/* FIXME: this is not very nice */
return (T)sqrt((double)sqlength(t));
}
@@ -396,8 +396,9 @@ static inline T sqlength(quat_t<T> const &t)
template<typename T> [[nodiscard]]
static inline T length(quat_t<T> const &t)
{
using std::sqrt;
/* FIXME: this is not very nice */
return (T)sqrt((double)sqlength(t));
return (T)sqrt(sqlength(t));
}

template<typename T> [[nodiscard]]
@@ -496,7 +497,99 @@ static inline sqt_t<T> operator /(sqt_t<T> const &x, sqt_t<T> const &y)
return x * inverse(y);
}

} /* namespace lol */
//
// Generic GLSL-like type names
//

#define T_(tleft, tright, suffix) \
typedef tleft half tright f16##suffix; \
typedef tleft float tright suffix; \
typedef tleft double tright d##suffix; \
typedef tleft ldouble tright f128##suffix; \
typedef tleft int8_t tright i8##suffix; \
typedef tleft uint8_t tright u8##suffix; \
typedef tleft int16_t tright i16##suffix; \
typedef tleft uint16_t tright u16##suffix; \
typedef tleft int32_t tright i##suffix; \
typedef tleft uint32_t tright u##suffix; \
typedef tleft int64_t tright i64##suffix; \
typedef tleft uint64_t tright u64##suffix; \
typedef tleft real tright r##suffix;

/* Idiotic hack to put "," inside a macro argument */
#define C_ ,

T_(mat_t<, C_ 2 C_ 2>, mat2)
T_(mat_t<, C_ 3 C_ 3>, mat3)
T_(mat_t<, C_ 4 C_ 4>, mat4)

T_(mat_t<, C_ 2 C_ 3>, mat2x3)
T_(mat_t<, C_ 2 C_ 4>, mat2x4)
T_(mat_t<, C_ 3 C_ 2>, mat3x2)
T_(mat_t<, C_ 3 C_ 4>, mat3x4)
T_(mat_t<, C_ 4 C_ 2>, mat4x2)
T_(mat_t<, C_ 4 C_ 3>, mat4x3)

T_(cmplx_t<, >, cmplx)
T_(quat_t<, >, quat)
T_(sqt_t<, >, sqt)

#undef C_
#undef T_

static_assert(sizeof(cmplx) == 8, "sizeof(cmplx) == 8");
static_assert(sizeof(dcmplx) == 16, "sizeof(dcmplx) == 16");

static_assert(sizeof(quat) == 16, "sizeof(quat) == 16");
static_assert(sizeof(dquat) == 32, "sizeof(dquat) == 32");

static_assert(sizeof(imat2) == 16, "sizeof(imat2) == 16");
static_assert(sizeof(mat2) == 16, "sizeof(mat2) == 16");
static_assert(sizeof(dmat2) == 32, "sizeof(dmat2) == 32");

static_assert(sizeof(imat3) == 36, "sizeof(imat3) == 36");
static_assert(sizeof(mat3) == 36, "sizeof(mat3) == 36");
static_assert(sizeof(dmat3) == 72, "sizeof(dmat3) == 72");

static_assert(sizeof(imat4) == 64, "sizeof(imat4) == 64");
static_assert(sizeof(mat4) == 64, "sizeof(mat4) == 64");
static_assert(sizeof(dmat4) == 128, "sizeof(dmat4) == 128");

//
// HLSL/Cg-compliant type names
//

typedef mat2 float2x2;
typedef mat3 float3x3;
typedef mat4 float4x4;
typedef mat2x3 float2x3;
typedef mat2x4 float2x4;
typedef mat3x2 float3x2;
typedef mat3x4 float3x4;
typedef mat4x2 float4x2;
typedef mat4x3 float4x3;

typedef f16mat2 half2x2;
typedef f16mat3 half3x3;
typedef f16mat4 half4x4;
typedef f16mat2x3 half2x3;
typedef f16mat2x4 half2x4;
typedef f16mat3x2 half3x2;
typedef f16mat3x4 half3x4;
typedef f16mat4x2 half4x2;
typedef f16mat4x3 half4x3;

typedef imat2 int2x2;
typedef imat3 int3x3;
typedef imat4 int4x4;
typedef imat2x3 int2x3;
typedef imat2x4 int2x4;
typedef imat3x2 int3x2;
typedef imat3x4 int3x4;
typedef imat4x2 int4x2;
typedef imat4x3 int4x3;

} // namespace lol

#include "private/matrix.ipp"
#include "private/transform.ipp"


+ 125
- 44
include/lol/math/vector.h Wyświetl plik

@@ -17,15 +17,21 @@
// ——————————————————
//

#include <lol/math/private/ops.h>

#include <cassert>
#include <ostream> // std::ostream
#include <type_traits>
#include <cmath> // std::fabs, std::cos…

// FIXME: get rid of this, too
#include <../legacy/lol/base/types.h>

#include "private/ops.h"

namespace lol
{

template<typename T> struct quat_t;

/*
* Magic vector swizzling
*
@@ -188,7 +194,7 @@ private:

static inline void internal_init(T *data)
{
UNUSED(data);
(void)data;
}

T m_data[count];
@@ -296,14 +302,6 @@ struct [[nodiscard]] vec_t<T,2>
};
};

static_assert(sizeof(i8vec2) == 2, "sizeof(i8vec2) == 2");
static_assert(sizeof(i16vec2) == 4, "sizeof(i16vec2) == 4");
static_assert(sizeof(ivec2) == 8, "sizeof(ivec2) == 8");
static_assert(sizeof(i64vec2) == 16, "sizeof(i64vec2) == 16");

static_assert(sizeof(vec2) == 8, "sizeof(vec2) == 8");
static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16");

/*
* 3-element vectors
*/
@@ -388,7 +386,9 @@ struct [[nodiscard]] vec_t<T,3>
/* Return a vector that is orthogonal to “a” */
friend inline type orthogonal(type const &a)
{
return lol::abs(a.x) > lol::abs(a.z)
using std::fabs;

return fabs(a.x) > fabs(a.z)
? type(-a.y, a.x, T(0))
: type(T(0), -a.z, a.y);
}
@@ -536,14 +536,6 @@ struct [[nodiscard]] vec_t<T,3>
};
};

static_assert(sizeof(i8vec3) == 3, "sizeof(i8vec3) == 3");
static_assert(sizeof(i16vec3) == 6, "sizeof(i16vec3) == 6");
static_assert(sizeof(ivec3) == 12, "sizeof(ivec3) == 12");
static_assert(sizeof(i64vec3) == 24, "sizeof(i64vec3) == 24");

static_assert(sizeof(vec3) == 12, "sizeof(vec3) == 12");
static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24");

/*
* 4-element vectors
*/
@@ -968,14 +960,6 @@ struct [[nodiscard]] vec_t<T,4>
};
};

static_assert(sizeof(i8vec4) == 4, "sizeof(i8vec4) == 4");
static_assert(sizeof(i16vec4) == 8, "sizeof(i16vec4) == 8");
static_assert(sizeof(ivec4) == 16, "sizeof(ivec4) == 16");
static_assert(sizeof(i64vec4) == 32, "sizeof(i64vec4) == 32");

static_assert(sizeof(vec4) == 16, "sizeof(vec4) == 16");
static_assert(sizeof(dvec4) == 32, "sizeof(dvec4) == 32");

/*
* stdstream method implementation
*/
@@ -1013,7 +997,6 @@ operator *(T const &val, vec_t<T,N,SWIZZLE> const &a)
inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE1> const &a, \
vec_t<T,N,SWIZZLE2> const &b) \
{ \
using lol::fun; \
vec_t<T,N> ret; \
for (int i = 0; i < N; ++i) \
ret[i] = fun(a[i], b[i]); \
@@ -1023,7 +1006,6 @@ operator *(T const &val, vec_t<T,N,SWIZZLE> const &a)
template<typename T, int N, int SWIZZLE> \
inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE> const &a, T const &b) \
{ \
using lol::fun; \
vec_t<T,N> ret; \
for (int i = 0; i < N; ++i) \
ret[i] = fun(a[i], b); \
@@ -1033,7 +1015,6 @@ operator *(T const &val, vec_t<T,N,SWIZZLE> const &a)
template<typename T, int N, int SWIZZLE> \
inline vec_t<T,N> fun(T const &a, vec_t<T,N,SWIZZLE> const &b) \
{ \
using lol::fun; \
vec_t<T,N> ret; \
for (int i = 0; i < N; ++i) \
ret[i] = fun(a, b[i]); \
@@ -1129,8 +1110,9 @@ static inline T sqlength(vec_t<T,N,SWIZZLE> const &a)
template<typename T, int N, int SWIZZLE> [[nodiscard]]
static inline T length(vec_t<T,N,SWIZZLE> const &a)
{
using std::sqrt;
/* FIXME: this is not very nice */
return T(sqrt((double)sqlength(a)));
return T(sqrt(sqlength(a)));
}

template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
@@ -1181,7 +1163,7 @@ static inline vec_t<T,N> abs(vec_t<T,N,SWIZZLE> const &a)
{
vec_t<T,N> ret;
for (int i = 0; i < N; ++i)
ret[i] = lol::abs(a[i]);
ret[i] = abs(a[i]);
return ret;
}

@@ -1190,7 +1172,7 @@ static inline vec_t<T,N> degrees(vec_t<T,N,SWIZZLE> const &a)
{
vec_t<T,N> ret;
for (int i = 0; i < N; ++i)
ret[i] = lol::degrees(a[i]);
ret[i] = degrees(a[i]);
return ret;
}

@@ -1199,7 +1181,7 @@ static inline vec_t<T, N> radians(vec_t<T, N, SWIZZLE> const &a)
{
vec_t<T, N> ret;
for (int i = 0; i < N; ++i)
ret[i] = lol::radians(a[i]);
ret[i] = radians(a[i]);
return ret;
}

@@ -1207,19 +1189,23 @@ static inline vec_t<T, N> radians(vec_t<T, N, SWIZZLE> const &a)
template<typename T, int SWIZZLE>
static inline vec_t<T, 2> cartesian(vec_t<T, 2, SWIZZLE> const &a)
{
using std::sin, std::cos;

vec_t<T, 2> ret;
ret.x = a[0] * lol::cos(a[1]);
ret.y = a[0] * lol::sin(a[1]);
ret.x = a[0] * cos(a[1]);
ret.y = a[0] * sin(a[1]);
return ret;
}

template<typename T, int SWIZZLE>
static inline vec_t<T, 3> cartesian(vec_t<T, 3, SWIZZLE> const &a)
{
using std::sin, std::cos;

vec_t<T, 3> ret;
ret.x = a[0] * lol::sin(a[2]) * lol::cos(a[1]);
ret.y = a[0] * lol::cos(a[2]);
ret.z = a[0] * lol::sin(a[2]) * lol::sin(a[1]);
ret.x = a[0] * sin(a[2]) * cos(a[1]);
ret.y = a[0] * cos(a[2]);
ret.z = a[0] * sin(a[2]) * sin(a[1]);
return ret;
}

@@ -1229,17 +1215,19 @@ static inline vec_t<T, 2> spherical(vec_t<T, 2, SWIZZLE> const &a)
{
vec_t<T, 2> ret;
ret[0] = sqlength(a);
ret[1] = lol::atan2(a.y, a.x);
ret[1] = atan2(a.y, a.x);
return ret;
}

template<typename T, int SWIZZLE>
static inline vec_t<T, 3> spherical(vec_t<T, 3, SWIZZLE> const &a)
{
using std::atan, std::acos;

vec_t<T, 3> ret;
ret[0] = sqlength(a);
ret[1] = lol::atan(a.y / a.x);
ret[2] = lol::acos(a.z / ret[0]);
ret[1] = atan(a.y / a.x);
ret[2] = acos(a.z / ret[0]);
return ret;
}

@@ -1334,7 +1322,100 @@ vec_t<T,4> const vec_t<T,4>::axis_z = vec_t<T,4>(T(0), T(0), T(1), T(0));
template<typename T>
vec_t<T,4> const vec_t<T,4>::axis_w = vec_t<T,4>(T(0), T(0), T(0), T(1));

} /* namespace lol */
//
// Generic GLSL-like type names
//

#define T_(tleft, tright, suffix) \
typedef tleft half tright f16##suffix; \
typedef tleft float tright suffix; \
typedef tleft double tright d##suffix; \
typedef tleft ldouble tright f128##suffix; \
typedef tleft int8_t tright i8##suffix; \
typedef tleft uint8_t tright u8##suffix; \
typedef tleft int16_t tright i16##suffix; \
typedef tleft uint16_t tright u16##suffix; \
typedef tleft int32_t tright i##suffix; \
typedef tleft uint32_t tright u##suffix; \
typedef tleft int64_t tright i64##suffix; \
typedef tleft uint64_t tright u64##suffix; \
typedef tleft real tright r##suffix;

// Idiotic hack to put "," inside a macro argument
#define C_ ,

T_(vec_t<, C_ 2>, vec2)
T_(vec_t<, C_ 3>, vec3)
T_(vec_t<, C_ 4>, vec4)
T_(vec_t<, C_ 5>, vec5)
T_(vec_t<, C_ 6>, vec6)
T_(vec_t<, C_ 7>, vec7)
T_(vec_t<, C_ 8>, vec8)
T_(vec_t<, C_ 9>, vec9)
T_(vec_t<, C_ 10>, vec10)
T_(vec_t<, C_ 11>, vec11)
T_(vec_t<, C_ 12>, vec12)

#undef C_
#undef T_

static_assert(sizeof(i8vec2) == 2, "sizeof(i8vec2) == 2");
static_assert(sizeof(i16vec2) == 4, "sizeof(i16vec2) == 4");
static_assert(sizeof(ivec2) == 8, "sizeof(ivec2) == 8");
static_assert(sizeof(i64vec2) == 16, "sizeof(i64vec2) == 16");

static_assert(sizeof(vec2) == 8, "sizeof(vec2) == 8");
static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16");

static_assert(sizeof(i8vec3) == 3, "sizeof(i8vec3) == 3");
static_assert(sizeof(i16vec3) == 6, "sizeof(i16vec3) == 6");
static_assert(sizeof(ivec3) == 12, "sizeof(ivec3) == 12");
static_assert(sizeof(i64vec3) == 24, "sizeof(i64vec3) == 24");

static_assert(sizeof(vec3) == 12, "sizeof(vec3) == 12");
static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24");

static_assert(sizeof(i8vec4) == 4, "sizeof(i8vec4) == 4");
static_assert(sizeof(i16vec4) == 8, "sizeof(i16vec4) == 8");
static_assert(sizeof(ivec4) == 16, "sizeof(ivec4) == 16");
static_assert(sizeof(i64vec4) == 32, "sizeof(i64vec4) == 32");

static_assert(sizeof(vec4) == 16, "sizeof(vec4) == 16");
static_assert(sizeof(dvec4) == 32, "sizeof(dvec4) == 32");

//
// HLSL/Cg-compliant type names
//

typedef vec2 float2;
typedef vec3 float3;
typedef vec4 float4;
typedef vec5 float5;
typedef vec6 float6;
typedef vec7 float7;
typedef vec8 float8;
typedef vec9 float9;
typedef vec10 float10;
typedef vec11 float11;
typedef vec12 float12;

typedef f16vec2 half2;
typedef f16vec3 half3;
typedef f16vec4 half4;

typedef ivec2 int2;
typedef ivec3 int3;
typedef ivec4 int4;
typedef ivec5 int5;
typedef ivec6 int6;
typedef ivec7 int7;
typedef ivec8 int8;
typedef ivec9 int9;
typedef ivec10 int10;
typedef ivec11 int11;
typedef ivec12 int12;

} // namespace lol

#include "private/vector.ipp"


+ 8
- 5
include/lol/types/half.h Wyświetl plik

@@ -21,6 +21,9 @@
#include <ostream> // std::ostream
#include <stdint.h> // uint32_t etc.

// FIXME: get rid of this
#include <../legacy/lol/math/functions.h>

namespace lol
{

@@ -41,7 +44,7 @@ public:
inline half() {}
explicit inline half(int f) : half(float(f)) {}
explicit inline half(double f) : half(float(f)) {}
explicit inline half(ldouble f) : half(float(f)) {}
explicit inline half(long double f) : half(float(f)) {}

explicit inline half(float f)
{
@@ -115,7 +118,7 @@ public:
inline half &operator =(int f) { return *this = half(f); }
inline half &operator =(float f) { return *this = half(f); }
inline half &operator =(double f) { return *this = half(f); }
inline half &operator =(ldouble f) { return *this = half(f); }
inline half &operator =(long double f) { return *this = half(f); }
[[nodiscard]] inline operator int8_t() const { return (int8_t)(float)*this; }
[[nodiscard]] inline operator uint8_t() const { return (uint8_t)(float)*this; }
[[nodiscard]] inline operator int16_t() const { return (int16_t)(float)*this; }
@@ -132,7 +135,7 @@ public:
}

[[nodiscard]] inline operator double() const { return (float)(*this); }
[[nodiscard]] inline operator ldouble() const { return (float)(*this); }
[[nodiscard]] inline operator long double() const { return (float)(*this); }

// Operators
[[nodiscard]] bool operator ==(half x) const { return (float)*this == (float)x; }
@@ -277,8 +280,8 @@ namespace half_ops
{ typedef float from; typedef TO to; };
template<typename TO> struct valid<double, TO>
{ typedef double from; typedef TO to; };
template<typename TO> struct valid<ldouble, TO>
{ typedef ldouble from; typedef TO to; };
template<typename TO> struct valid<long double, TO>
{ typedef long double from; typedef TO to; };

#define DECLARE_HALF_NUMERIC_OPS(op) \
/* other + half */ \


+ 0
- 128
legacy/lol/base/types.h Wyświetl plik

@@ -25,133 +25,5 @@ typedef real_t<uint32_t> real;

class half;

/*
* Forward declaration of vec_t, mat_t, cmplx_t, quat_t, etc.
*/

/* HACK: if this is declared int const, Visual Studio becomes unable
* to perform template argument deduction. */
#define FULL_SWIZZLE (0)

template<typename T, int N, int SWIZZLE = FULL_SWIZZLE> struct vec_t;
template<typename T, int N> struct box_t;
template<typename T, int COLS, int ROWS> struct mat_t;
template<typename T> struct cmplx_t;
template<typename T> struct quat_t;
template<typename T> struct dualquat_t;
template<typename T> struct sqt_t;

/*
* Generic GLSL-like type names
*/

#define T_(tleft, tright, suffix) \
typedef tleft half tright f16##suffix; \
typedef tleft float tright suffix; \
typedef tleft double tright d##suffix; \
typedef tleft ldouble tright f128##suffix; \
typedef tleft int8_t tright i8##suffix; \
typedef tleft uint8_t tright u8##suffix; \
typedef tleft int16_t tright i16##suffix; \
typedef tleft uint16_t tright u16##suffix; \
typedef tleft int32_t tright i##suffix; \
typedef tleft uint32_t tright u##suffix; \
typedef tleft int64_t tright i64##suffix; \
typedef tleft uint64_t tright u64##suffix; \
typedef tleft real tright r##suffix;

/* Idiotic hack to put "," inside a macro argument */
#define C_ ,

T_(vec_t<, C_ 2>, vec2)
T_(vec_t<, C_ 3>, vec3)
T_(vec_t<, C_ 4>, vec4)
T_(vec_t<, C_ 5>, vec5)
T_(vec_t<, C_ 6>, vec6)
T_(vec_t<, C_ 7>, vec7)
T_(vec_t<, C_ 8>, vec8)
T_(vec_t<, C_ 9>, vec9)
T_(vec_t<, C_ 10>, vec10)
T_(vec_t<, C_ 11>, vec11)
T_(vec_t<, C_ 12>, vec12)

T_(mat_t<, C_ 2 C_ 2>, mat2)
T_(mat_t<, C_ 3 C_ 3>, mat3)
T_(mat_t<, C_ 4 C_ 4>, mat4)

T_(mat_t<, C_ 2 C_ 3>, mat2x3)
T_(mat_t<, C_ 2 C_ 4>, mat2x4)
T_(mat_t<, C_ 3 C_ 2>, mat3x2)
T_(mat_t<, C_ 3 C_ 4>, mat3x4)
T_(mat_t<, C_ 4 C_ 2>, mat4x2)
T_(mat_t<, C_ 4 C_ 3>, mat4x3)

T_(cmplx_t<, >, cmplx)
T_(quat_t<, >, quat)
T_(dualquat_t<, >, dualquat)
T_(sqt_t<, >, sqt)

#undef C_
#undef T_

/*
* HLSL/Cg-compliant type names
*/

typedef vec2 float2;
typedef vec3 float3;
typedef vec4 float4;
typedef vec5 float5;
typedef vec6 float6;
typedef vec7 float7;
typedef vec8 float8;
typedef vec9 float9;
typedef vec10 float10;
typedef vec11 float11;
typedef vec12 float12;
typedef mat2 float2x2;
typedef mat3 float3x3;
typedef mat4 float4x4;
typedef mat2x3 float2x3;
typedef mat2x4 float2x4;
typedef mat3x2 float3x2;
typedef mat3x4 float3x4;
typedef mat4x2 float4x2;
typedef mat4x3 float4x3;

typedef f16vec2 half2;
typedef f16vec3 half3;
typedef f16vec4 half4;
typedef f16mat2 half2x2;
typedef f16mat3 half3x3;
typedef f16mat4 half4x4;
typedef f16mat2x3 half2x3;
typedef f16mat2x4 half2x4;
typedef f16mat3x2 half3x2;
typedef f16mat3x4 half3x4;
typedef f16mat4x2 half4x2;
typedef f16mat4x3 half4x3;

typedef ivec2 int2;
typedef ivec3 int3;
typedef ivec4 int4;
typedef ivec5 int5;
typedef ivec6 int6;
typedef ivec7 int7;
typedef ivec8 int8;
typedef ivec9 int9;
typedef ivec10 int10;
typedef ivec11 int11;
typedef ivec12 int12;
typedef imat2 int2x2;
typedef imat3 int3x3;
typedef imat4 int4x4;
typedef imat2x3 int2x3;
typedef imat2x4 int2x4;
typedef imat3x2 int3x2;
typedef imat3x4 int3x4;
typedef imat4x2 int4x2;
typedef imat4x3 int4x3;

} /* namespace lol */


+ 28
- 26
legacy/lol/math/geometry.h Wyświetl plik

@@ -19,7 +19,9 @@
//

#include <lol/base/enum.h>
#include <lol/math/vector.h> // vec_t
#include <lol/math/vector.h> // vec_t
#include <lol/math/transform.h> // mat_t
#include <../legacy/lol/math/functions.h> // distance, clamp…

#include <algorithm>
#include <map>
@@ -71,26 +73,6 @@ protected:
};
typedef SafeEnum<DirectionBase> Direction;

/*
* Generic box type names
*/

#define T_(tleft, tright, suffix) \
typedef tleft float tright suffix; \
typedef tleft double tright d##suffix; \
typedef tleft int32_t tright i##suffix; \
typedef tleft uint32_t tright u##suffix;

/* Idiotic hack to put "," inside a macro argument */
#define C_ ,

T_(box_t<, C_ 2>, box2)
T_(box_t<, C_ 3>, box3)
T_(box_t<, C_ 4>, box4)

#undef C_
#undef T_

template<typename T, int N>
struct [[nodiscard]] box_t
{
@@ -172,6 +154,26 @@ struct [[nodiscard]] box_t
vec_t<T,N> aa, bb;
};

//
// Generic box type names
//

#define T_(tleft, tright, suffix) \
typedef tleft float tright suffix; \
typedef tleft double tright d##suffix; \
typedef tleft int32_t tright i##suffix; \
typedef tleft uint32_t tright u##suffix;

// Idiotic hack to put "," inside a macro argument
#define C_ ,

T_(box_t<, C_ 2>, box2)
T_(box_t<, C_ 3>, box3)
T_(box_t<, C_ 4>, box4)

#undef C_
#undef T_

static_assert(sizeof(box2) == 16, "sizeof(box2) == 16");
static_assert(sizeof(box3) == 24, "sizeof(box3) == 24");
static_assert(sizeof(dbox2) == 32, "sizeof(dbox2) == 32");
@@ -215,8 +217,8 @@ static inline bool TestAABBVsAABB(box2 const &b1, box2 const &b2)
vec2 e1 = 0.5f * b1.extent();
vec2 e2 = 0.5f * b2.extent();

return abs(c.x) <= e1.x + e2.x
&& abs(c.y) <= e1.y + e2.y;
return fabs(c.x) <= e1.x + e2.x
&& fabs(c.y) <= e1.y + e2.y;
}
static inline bool TestAABBVsPoint(box2 const &b1, vec2 const &p)
{
@@ -229,9 +231,9 @@ static inline bool TestAABBVsAABB(box3 const &b1, box3 const &b2)
vec3 e1 = 0.5f * b1.extent();
vec3 e2 = 0.5f * b2.extent();

return abs(c.x) <= e1.x + e2.x
&& abs(c.y) <= e1.y + e2.y
&& abs(c.z) <= e1.z + e2.z;
return fabs(c.x) <= e1.x + e2.x
&& fabs(c.y) <= e1.y + e2.y
&& fabs(c.z) <= e1.z + e2.z;
}
static inline bool TestAABBVsPoint(box3 const &b1, vec3 const &p)
{


+ 9
- 5
legacy/lol/math/noise/gradient.h Wyświetl plik

@@ -14,7 +14,11 @@

#pragma once

#include <functional>
#include <lol/math/vector.h> // vec_t
#include <lol/math/rand.h> // rand()

#include <vector> // std::vector
#include <algorithm> // std::min

namespace lol
{
@@ -58,22 +62,22 @@ protected:

/* Generate 2^(N+2) random vectors, but at least 2^5 (32) and not
* more than 2^20 (~ 1 million). */
int const gradient_count = 1 << min(max(N + 2, 5), 20);
int constexpr gradient_count = 1 << std::min(std::max(N + 2, 5), 20);

static auto build_gradients = [&]()
{
array<vec_t<float, N>> ret;
std::array<vec_t<float, N>, gradient_count> ret;
for (int k = 0; k < gradient_count; ++k)
{
vec_t<float, N> v;
for (int i = 0; i < N; ++i)
v[i] = rand(-1.f, 1.f);
ret << normalize(v);
ret[k] = normalize(v);
}
return ret;
};

static array<vec_t<float, N>> const gradients = build_gradients();
static auto const gradients = build_gradients();

int idx = m_seed;
for (int i = 0; i < N; ++i)


+ 23
- 16
legacy/lol/math/noise/simplex.h Wyświetl plik

@@ -1,7 +1,7 @@
//
// Lol Engine
//
// Copyright © 2010—2014 Sam Hocevar <sam@hocevar.net>
// Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net>
// © 2013—2014 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
// © 2013—2014 Guillaume Bittoun <guillaume.bittoun@gmail.com>
//
@@ -15,6 +15,11 @@
#pragma once

#include <../legacy/lol/math/noise/gradient.h>
#include <lol/math/vector.h> // vec_t
#include <lol/math/transform.h> // mat_t

#include <vector> // std::vector
#include <algorithm> // std::min, std::max

namespace lol
{
@@ -106,7 +111,6 @@ protected:
* coordinates. */
vec_t<float, N> world_corner(0.f);
float result = 0.f, sum = 0.f, special = 0.f;
UNUSED(sum, special);

for (int i = 0; i < N + 1; ++i)
{
@@ -137,9 +141,9 @@ protected:
// -4.f: centre (-2.f),
// -3.f: r=0.38 sphere of influence (contribution = 1/4)
// -2.f: r=0.52 sphere of influence (contribution = 1/24)
if (d > 0.99f) special = min(special, -4.f);
if (d > 0.7f && d < 0.72f) special = min(special, -3.f);
if (d > 0.44f && d < 0.46f) special = min(special, -2.f);
if (d > 0.99f) special = std::min(special, -4.f);
if (d > 0.7f && d < 0.72f) special = std::min(special, -3.f);
if (d > 0.44f && d < 0.46f) special = std::min(special, -2.f);
#endif

if (d > 0)
@@ -168,6 +172,8 @@ protected:
#if 0
if (special < 0.f)
return special;
#else
(void)special;
#endif

return get_scale() * result;
@@ -275,8 +281,8 @@ private:
continue;

float l = length(vertices[i] - vertices[j]);
minlength = min(minlength, l);
maxlength = max(maxlength, l);
minlength = std::min(minlength, l);
maxlength = std::max(maxlength, l);
}
printf(" · edge lengths between %f and %f\n",
minlength, maxlength);
@@ -300,7 +306,7 @@ private:
p += k * vertices[j];
sum += k;
}
mindist = min(mindist, distance(vertices[i], p / sum));
mindist = std::min(mindist, distance(vertices[i], p / sum));
}
printf(" · approx. dist. to opposite hyperplane: %f\n", mindist);
#endif
@@ -327,7 +333,7 @@ private:
/* Find distance from current vertex to the opposite hyperplane.
* Just use the projection theorem in N dimensions. */
auto w = vertices[i] - vertices[i0];
float dist = abs(dot(normal, w));
float dist = fabs(dot(normal, w));
printf(" · distance to opposite hyperplane: %f\n", dist);
#endif
}
@@ -345,11 +351,12 @@ private:

/* Try to find max noise value by climbing gradient */
float minval = 0.f, maxval = 0.f;
array<vec_t<float, N>> deltas;
std::vector<vec_t<float, N>> deltas;
for (int i = 0; i < N; ++i)
{
auto v = vec_t<float, N>::axis(i);
deltas << v << -v;
deltas.push_back(v);
deltas.push_back(-v);
}
for (int run = 0; run < 1000; ++run)
{
@@ -364,10 +371,10 @@ private:
{
int best_delta = -1;
float best_t2 = t;
for (int i = 0; i < deltas.count(); ++i)
for (int i = 0; i < (int)deltas.size(); ++i)
{
float t2 = eval(v + e * deltas[i]);
if (abs(t2) > abs(best_t2))
if (fabs(t2) > fabs(best_t2))
{
best_delta = i;
best_t2 = t2;
@@ -381,11 +388,11 @@ private:
t = best_t2;
}
}
minval = min(t, minval);
maxval = max(t, maxval);
minval = std::min(t, minval);
maxval = std::max(t, maxval);
}
printf(" - noise value min/max: %f %f\n", minval, maxval);
float newscale = 1.f / max(-minval, maxval);
float newscale = 1.f / std::max(-minval, maxval);
if (newscale < 1.f)
printf(" - could replace scale %f with %f\n",
get_scale(), newscale * get_scale());


Ładowanie…
Anuluj
Zapisz