Skip to content

Commit

Permalink
remove IntegralConstant hack
Browse files Browse the repository at this point in the history
  • Loading branch information
Garux committed Mar 25, 2021
1 parent dc5dea6 commit f8ab9a3
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 102 deletions.
54 changes: 27 additions & 27 deletions libs/math/aabb.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,39 +66,39 @@ inline AABB aabb_for_minmax( const Vector3& min, const Vector3& max ){
return aabb;
}

template<typename Index>
template<size_t Index>
class AABBExtend
{
public:
static void apply( AABB& aabb, const Vector3& point ){
float displacement = point[Index::VALUE] - aabb.origin[Index::VALUE];
float half_difference = static_cast<float>( 0.5 * ( fabs( displacement ) - aabb.extents[Index::VALUE] ) );
float displacement = point[Index] - aabb.origin[Index];
float half_difference = static_cast<float>( 0.5 * ( fabs( displacement ) - aabb.extents[Index] ) );
if ( half_difference > 0.0f ) {
aabb.origin[Index::VALUE] += ( displacement >= 0.0f ) ? half_difference : -half_difference;
aabb.extents[Index::VALUE] += half_difference;
aabb.origin[Index] += ( displacement >= 0.0f ) ? half_difference : -half_difference;
aabb.extents[Index] += half_difference;
}
}
static void apply( AABB& aabb, const AABB& other ){
float displacement = other.origin[Index::VALUE] - aabb.origin[Index::VALUE];
float difference = other.extents[Index::VALUE] - aabb.extents[Index::VALUE];
float displacement = other.origin[Index] - aabb.origin[Index];
float difference = other.extents[Index] - aabb.extents[Index];
if ( fabs( displacement ) > fabs( difference ) ) {
float half_difference = static_cast<float>( 0.5 * ( fabs( displacement ) + difference ) );
if ( half_difference > 0.0f ) {
aabb.origin[Index::VALUE] += ( displacement >= 0.0f ) ? half_difference : -half_difference;
aabb.extents[Index::VALUE] += half_difference;
aabb.origin[Index] += ( displacement >= 0.0f ) ? half_difference : -half_difference;
aabb.extents[Index] += half_difference;
}
}
else if ( difference > 0.0f ) {
aabb.origin[Index::VALUE] = other.origin[Index::VALUE];
aabb.extents[Index::VALUE] = other.extents[Index::VALUE];
aabb.origin[Index] = other.origin[Index];
aabb.extents[Index] = other.extents[Index];
}
}
};

inline void aabb_extend_by_point( AABB& aabb, const Vector3& point ){
AABBExtend< IntegralConstant<0> >::apply( aabb, point );
AABBExtend< IntegralConstant<1> >::apply( aabb, point );
AABBExtend< IntegralConstant<2> >::apply( aabb, point );
AABBExtend< 0 >::apply( aabb, point );
AABBExtend< 1 >::apply( aabb, point );
AABBExtend< 2 >::apply( aabb, point );
}

inline void aabb_extend_by_point_safe( AABB& aabb, const Vector3& point ){
Expand All @@ -124,9 +124,9 @@ class AABBExtendByPoint
};

inline void aabb_extend_by_aabb( AABB& aabb, const AABB& other ){
AABBExtend< IntegralConstant<0> >::apply( aabb, other );
AABBExtend< IntegralConstant<1> >::apply( aabb, other );
AABBExtend< IntegralConstant<2> >::apply( aabb, other );
AABBExtend< 0 >::apply( aabb, other );
AABBExtend< 1 >::apply( aabb, other );
AABBExtend< 2 >::apply( aabb, other );
}

inline void aabb_extend_by_aabb_safe( AABB& aabb, const AABB& other ){
Expand All @@ -145,26 +145,26 @@ inline void aabb_extend_by_vec3( AABB& aabb, const Vector3& extension ){



template<typename Index>
template<size_t Index>
inline bool aabb_intersects_point_dimension( const AABB& aabb, const Vector3& point ){
return fabs( point[Index::VALUE] - aabb.origin[Index::VALUE] ) < aabb.extents[Index::VALUE];
return fabs( point[Index] - aabb.origin[Index] ) < aabb.extents[Index];
}

inline bool aabb_intersects_point( const AABB& aabb, const Vector3& point ){
return aabb_intersects_point_dimension< IntegralConstant<0> >( aabb, point )
&& aabb_intersects_point_dimension< IntegralConstant<1> >( aabb, point )
&& aabb_intersects_point_dimension< IntegralConstant<2> >( aabb, point );
return aabb_intersects_point_dimension< 0 >( aabb, point )
&& aabb_intersects_point_dimension< 1 >( aabb, point )
&& aabb_intersects_point_dimension< 2 >( aabb, point );
}

template<typename Index>
template<size_t Index>
inline bool aabb_intersects_aabb_dimension( const AABB& aabb, const AABB& other ){
return fabs( other.origin[Index::VALUE] - aabb.origin[Index::VALUE] ) < ( aabb.extents[Index::VALUE] + other.extents[Index::VALUE] );
return fabs( other.origin[Index] - aabb.origin[Index] ) < ( aabb.extents[Index] + other.extents[Index] );
}

inline bool aabb_intersects_aabb( const AABB& aabb, const AABB& other ){
return aabb_intersects_aabb_dimension< IntegralConstant<0> >( aabb, other )
&& aabb_intersects_aabb_dimension< IntegralConstant<1> >( aabb, other )
&& aabb_intersects_aabb_dimension< IntegralConstant<2> >( aabb, other );
return aabb_intersects_aabb_dimension< 0 >( aabb, other )
&& aabb_intersects_aabb_dimension< 1 >( aabb, other )
&& aabb_intersects_aabb_dimension< 2 >( aabb, other );
}

inline unsigned int aabb_classify_plane( const AABB& aabb, const Plane3& plane ){
Expand Down
36 changes: 15 additions & 21 deletions libs/math/curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,94 +30,88 @@
#include <math/matrix.h>


template<typename I, typename Degree>
template<int I, int Degree>
struct BernsteinPolynomial
{
static double apply( double t ){
return 1; // general case not implemented
}
};

typedef IntegralConstant<0> Zero;
typedef IntegralConstant<1> One;
typedef IntegralConstant<2> Two;
typedef IntegralConstant<3> Three;
typedef IntegralConstant<4> Four;

template<>
struct BernsteinPolynomial<Zero, Zero>
struct BernsteinPolynomial<0, 0>
{
static double apply( double t ){
return 1;
}
};

template<>
struct BernsteinPolynomial<Zero, One>
struct BernsteinPolynomial<0, 1>
{
static double apply( double t ){
return 1 - t;
}
};

template<>
struct BernsteinPolynomial<One, One>
struct BernsteinPolynomial<1, 1>
{
static double apply( double t ){
return t;
}
};

template<>
struct BernsteinPolynomial<Zero, Two>
struct BernsteinPolynomial<0, 2>
{
static double apply( double t ){
return ( 1 - t ) * ( 1 - t );
}
};

template<>
struct BernsteinPolynomial<One, Two>
struct BernsteinPolynomial<1, 2>
{
static double apply( double t ){
return 2 * ( 1 - t ) * t;
}
};

template<>
struct BernsteinPolynomial<Two, Two>
struct BernsteinPolynomial<2, 2>
{
static double apply( double t ){
return t * t;
}
};

template<>
struct BernsteinPolynomial<Zero, Three>
struct BernsteinPolynomial<0, 3>
{
static double apply( double t ){
return ( 1 - t ) * ( 1 - t ) * ( 1 - t );
}
};

template<>
struct BernsteinPolynomial<One, Three>
struct BernsteinPolynomial<1, 3>
{
static double apply( double t ){
return 3 * ( 1 - t ) * ( 1 - t ) * t;
}
};

template<>
struct BernsteinPolynomial<Two, Three>
struct BernsteinPolynomial<2, 3>
{
static double apply( double t ){
return 3 * ( 1 - t ) * t * t;
}
};

template<>
struct BernsteinPolynomial<Three, Three>
struct BernsteinPolynomial<3, 3>
{
static double apply( double t ){
return t * t * t;
Expand All @@ -131,22 +125,22 @@ inline Vector3 CubicBezier_evaluate( const Vector3* firstPoint, double t ){
double denominator = 0;

{
double weight = BernsteinPolynomial<Zero, Three>::apply( t );
double weight = BernsteinPolynomial<0, 3>::apply( t );
result += vector3_scaled( *firstPoint++, weight );
denominator += weight;
}
{
double weight = BernsteinPolynomial<One, Three>::apply( t );
double weight = BernsteinPolynomial<1, 3>::apply( t );
result += vector3_scaled( *firstPoint++, weight );
denominator += weight;
}
{
double weight = BernsteinPolynomial<Two, Three>::apply( t );
double weight = BernsteinPolynomial<2, 3>::apply( t );
result += vector3_scaled( *firstPoint++, weight );
denominator += weight;
}
{
double weight = BernsteinPolynomial<Three, Three>::apply( t );
double weight = BernsteinPolynomial<3, 3>::apply( t );
result += vector3_scaled( *firstPoint++, weight );
denominator += weight;
}
Expand Down
7 changes: 7 additions & 0 deletions libs/math/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@

#include <math/matrix.h>

/// \brief A compile-time-constant integer.
template<int VALUE_>
struct IntegralConstant
{
enum unnamed_ { VALUE = VALUE_ };
};

template<typename Value>
class Literal
{
Expand Down
36 changes: 18 additions & 18 deletions libs/math/frustum.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,27 @@ const ClipResult c_CLIP_LT_Z = 0x10; // 010000
const ClipResult c_CLIP_GT_Z = 0x20; // 100000
const ClipResult c_CLIP_FAIL = 0x3F; // 111111

template<typename Index>
template<size_t Index>
class Vector4ClipLT
{
public:
static bool compare( const Vector4& self ){
return self[Index::VALUE] < self[3];
return self[Index] < self[3];
}
static double scale( const Vector4& self, const Vector4& other ){
return ( self[Index::VALUE] - self[3] ) / ( other[3] - other[Index::VALUE] );
return ( self[Index] - self[3] ) / ( other[3] - other[Index] );
}
};

template<typename Index>
template<size_t Index>
class Vector4ClipGT
{
public:
static bool compare( const Vector4& self ){
return self[Index::VALUE] > -self[3];
return self[Index] > -self[3];
}
static double scale( const Vector4& self, const Vector4& other ){
return ( self[Index::VALUE] + self[3] ) / ( -other[3] - other[Index::VALUE] );
return ( self[Index] + self[3] ) / ( -other[3] - other[Index] );
}
};

Expand Down Expand Up @@ -131,12 +131,12 @@ class Vector4ClipPolygon
}
};

#define CLIP_X_LT_W( p ) ( Vector4ClipLT< IntegralConstant<0> >::compare( p ) )
#define CLIP_X_GT_W( p ) ( Vector4ClipGT< IntegralConstant<0> >::compare( p ) )
#define CLIP_Y_LT_W( p ) ( Vector4ClipLT< IntegralConstant<1> >::compare( p ) )
#define CLIP_Y_GT_W( p ) ( Vector4ClipGT< IntegralConstant<1> >::compare( p ) )
#define CLIP_Z_LT_W( p ) ( Vector4ClipLT< IntegralConstant<2> >::compare( p ) )
#define CLIP_Z_GT_W( p ) ( Vector4ClipGT< IntegralConstant<2> >::compare( p ) )
#define CLIP_X_LT_W( p ) ( Vector4ClipLT< 0 >::compare( p ) )
#define CLIP_X_GT_W( p ) ( Vector4ClipGT< 0 >::compare( p ) )
#define CLIP_Y_LT_W( p ) ( Vector4ClipLT< 1 >::compare( p ) )
#define CLIP_Y_GT_W( p ) ( Vector4ClipGT< 1 >::compare( p ) )
#define CLIP_Z_LT_W( p ) ( Vector4ClipLT< 2 >::compare( p ) )
#define CLIP_Z_GT_W( p ) ( Vector4ClipGT< 2 >::compare( p ) )

inline ClipResult homogenous_clip_point( const Vector4& clipped ){
ClipResult result = c_CLIP_FAIL;
Expand Down Expand Up @@ -177,12 +177,12 @@ inline ClipResult matrix4_clip_point( const Matrix4& self, const Vector3& point,
inline std::size_t homogenous_clip_triangle( Vector4 clipped[9] ){
Vector4 buffer[9];
std::size_t count = 3;
count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<0> > >::apply( clipped, clipped + count, buffer );
count = Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<0> > >::apply( buffer, buffer + count, clipped );
count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<1> > >::apply( clipped, clipped + count, buffer );
count = Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<1> > >::apply( buffer, buffer + count, clipped );
count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<2> > >::apply( clipped, clipped + count, buffer );
return Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<2> > >::apply( buffer, buffer + count, clipped );
count = Vector4ClipPolygon< Vector4ClipLT< 0 > >::apply( clipped, clipped + count, buffer );
count = Vector4ClipPolygon< Vector4ClipGT< 0 > >::apply( buffer, buffer + count, clipped );
count = Vector4ClipPolygon< Vector4ClipLT< 1 > >::apply( clipped, clipped + count, buffer );
count = Vector4ClipPolygon< Vector4ClipGT< 1 > >::apply( buffer, buffer + count, clipped );
count = Vector4ClipPolygon< Vector4ClipLT< 2 > >::apply( clipped, clipped + count, buffer );
return Vector4ClipPolygon< Vector4ClipGT< 2 > >::apply( buffer, buffer + count, clipped );
}

/// \brief Transforms and clips the triangle formed by \p p0, \p p1, \p p2 by the canonical matrix \p self.
Expand Down
52 changes: 19 additions & 33 deletions libs/math/matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,55 +501,41 @@ inline void matrix4_affine_invert( Matrix4& self ){
self = matrix4_affine_inverse( self );
}

/// \brief A compile-time-constant integer.
template<int VALUE_>
struct IntegralConstant
{
enum unnamed_ { VALUE = VALUE_ };
};

/// \brief A compile-time-constant row/column index into a 4x4 matrix.
template<typename Row, typename Col>
class Matrix4Index
{
public:
typedef IntegralConstant<Row::VALUE> r;
typedef IntegralConstant<Col::VALUE> c;
typedef IntegralConstant<( r::VALUE * 4 ) + c::VALUE> i;
};

/// \brief A functor which returns the cofactor of a 3x3 submatrix obtained by ignoring a given row and column of a 4x4 matrix.
/// \param Row Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three rows to use.
/// \param Col Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three columns to use.
template<typename Row, typename Col>
class Matrix4Cofactor
{
static constexpr size_t Matrix4Index( size_t row, size_t col ){
return ( row * 4 ) + col;
}
public:
typedef typename Matrix4Index<typename Row::x, typename Col::x>::i xx;
typedef typename Matrix4Index<typename Row::x, typename Col::y>::i xy;
typedef typename Matrix4Index<typename Row::x, typename Col::z>::i xz;
typedef typename Matrix4Index<typename Row::y, typename Col::x>::i yx;
typedef typename Matrix4Index<typename Row::y, typename Col::y>::i yy;
typedef typename Matrix4Index<typename Row::y, typename Col::z>::i yz;
typedef typename Matrix4Index<typename Row::z, typename Col::x>::i zx;
typedef typename Matrix4Index<typename Row::z, typename Col::y>::i zy;
typedef typename Matrix4Index<typename Row::z, typename Col::z>::i zz;
static constexpr size_t xx = Matrix4Index( Row::x, Col::x );
static constexpr size_t xy = Matrix4Index( Row::x, Col::y );
static constexpr size_t xz = Matrix4Index( Row::x, Col::z );
static constexpr size_t yx = Matrix4Index( Row::y, Col::x );
static constexpr size_t yy = Matrix4Index( Row::y, Col::y );
static constexpr size_t yz = Matrix4Index( Row::y, Col::z );
static constexpr size_t zx = Matrix4Index( Row::z, Col::x );
static constexpr size_t zy = Matrix4Index( Row::z, Col::y );
static constexpr size_t zz = Matrix4Index( Row::z, Col::z );
static double apply( const Matrix4& self ){
return self[xx::VALUE] * ( self[yy::VALUE] * self[zz::VALUE] - self[zy::VALUE] * self[yz::VALUE] )
- self[xy::VALUE] * ( self[yx::VALUE] * self[zz::VALUE] - self[zx::VALUE] * self[yz::VALUE] )
+ self[xz::VALUE] * ( self[yx::VALUE] * self[zy::VALUE] - self[zx::VALUE] * self[yy::VALUE] );
return self[xx] * ( self[yy] * self[zz] - self[zy] * self[yz] )
- self[xy] * ( self[yx] * self[zz] - self[zx] * self[yz] )
+ self[xz] * ( self[yx] * self[zy] - self[zx] * self[yy] );
}
};

/// \brief The cofactor element indices for a 4x4 matrix row or column.
/// \param Element The index of the element to ignore.
template<int Element>
template<size_t Element>
class Cofactor4
{
public:
typedef IntegralConstant<( Element <= 0 ) ? 1 : 0> x;
typedef IntegralConstant<( Element <= 1 ) ? 2 : 1> y;
typedef IntegralConstant<( Element <= 2 ) ? 3 : 2> z;
static constexpr size_t x = ( Element <= 0 ) ? 1 : 0;
static constexpr size_t y = ( Element <= 1 ) ? 2 : 1;
static constexpr size_t z = ( Element <= 2 ) ? 3 : 2;
};

/// \brief Returns the determinant of \p self.
Expand Down

0 comments on commit f8ab9a3

Please sign in to comment.