Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/Math/Test/SwizzleTest.cpp
Vladimír Vondruš 14 years ago
parent
commit
bd2cff9e7a
  1. 49
      src/Contexts/EglContext.h
  2. 10
      src/Math/Matrix.h
  3. 51
      src/Math/Swizzle.h
  4. 29
      src/Math/Test/SwizzleTest.cpp
  5. 1
      src/Math/Test/SwizzleTest.h
  6. 18
      src/Math/Vector.h

49
src/Contexts/EglContext.h

@ -100,7 +100,54 @@ class EglContext: public AbstractContext {
Home = XK_Home, /**< Home */
End = XK_End, /**< End */
PageUp = XK_Page_Up, /**< Page up */
PageDown = XK_Page_Down /**< Page down */
PageDown = XK_Page_Down, /**< Page down */
Space = XK_space, /**< Space */
Comma = XK_comma, /**< Comma */
Period = XK_period, /**< Period */
Minus = XK_minus, /**< Minus */
Plus = XK_plus, /**< Plus */
Slash = XK_slash, /**< Slash */
Percent = XK_percent, /**< Percent */
Equal = XK_equal, /**< Equal */
Zero = XK_0, /**< Zero */
One = XK_1, /**< One */
Two = XK_2, /**< Two */
Three = XK_3, /**< Three */
Four = XK_4, /**< Four */
Five = XK_5, /**< Five */
Six = XK_6, /**< Six */
Seven = XK_7, /**< Seven */
Eight = XK_8, /**< Eight */
Nine = XK_9, /**< Nine */
A = XK_a, /**< Small letter A */
B = XK_b, /**< Small letter B */
C = XK_c, /**< Small letter C */
D = XK_d, /**< Small letter D */
E = XK_e, /**< Small letter E */
F = XK_f, /**< Small letter F */
G = XK_g, /**< Small letter G */
H = XK_h, /**< Small letter H */
I = XK_i, /**< Small letter I */
J = XK_j, /**< Small letter J */
K = XK_k, /**< Small letter K */
L = XK_l, /**< Small letter L */
M = XK_m, /**< Small letter M */
N = XK_n, /**< Small letter N */
O = XK_o, /**< Small letter O */
P = XK_p, /**< Small letter P */
Q = XK_q, /**< Small letter Q */
R = XK_r, /**< Small letter R */
S = XK_s, /**< Small letter S */
T = XK_t, /**< Small letter T */
U = XK_u, /**< Small letter U */
V = XK_v, /**< Small letter V */
W = XK_w, /**< Small letter W */
X = XK_x, /**< Small letter X */
Y = XK_y, /**< Small letter Y */
Z = XK_z /**< Small letter Z */
};
protected:

10
src/Math/Matrix.h

@ -26,16 +26,6 @@ namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<size_t size, class T> class MatrixDeterminant;
template<size_t ...> struct Sequence {};
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<size_t N, size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
template<size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
}
#endif

51
src/Math/Swizzle.h

@ -48,6 +48,26 @@ namespace Implementation {
template<class T> struct TypeForSize<2, T> { typedef Vector2<T> Type; };
template<class T> struct TypeForSize<3, T> { typedef Vector3<T> Type; };
template<class T> struct TypeForSize<4, T> { typedef Vector4<T> Type; };
inline constexpr size_t getPosition(size_t size, size_t position) {
return size > position ? position : throw;
}
template<size_t size> inline constexpr size_t getComponent(char component) {
return component == 'x' ? getPosition(size, 0) :
component == 'y' ? getPosition(size, 1) :
component == 'z' ? getPosition(size, 2) :
component == 'w' ? getPosition(size, 3) :
component == 'r' ? getPosition(size, 0) :
component == 'g' ? getPosition(size, 1) :
component == 'b' ? getPosition(size, 2) :
component == 'a' ? getPosition(size, 3) :
throw;
}
template<size_t size, class T, size_t ...sequence> inline constexpr Vector<sizeof...(sequence), T> swizzleFrom(Sequence<sequence...>, const Vector<size, T>& vector, const char(&components)[sizeof...(sequence)+1]) {
return {vector[getComponent<size>(components[sequence])]...};
}
}
#endif
@ -66,12 +86,43 @@ elements is unlimited, but must be at least one. If the resulting vector is
two, three or four-component, corresponding Vector2, Vector3 or Vector4
specialization is returned.
@attention This function is less convenient to write than
swizzle(const Vector<size, T>&, const char(&)[newSize]), but the evaluation of
the swizzling operation is guaranteed to be always done at compile time
instead of at runtime.
@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy()
*/
template<char ...components, size_t size, class T> inline constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const Vector<size, T>& vector) {
return {vector[Implementation::GetComponent<size, components>::value()]...};
}
/**
@brief Swizzle Vector components
Creates new vector from given components. Example:
@code
Vector4<int> original(1, 2, 3, 4);
auto vec = swizzle(original, "abbgrr");
// vec == { 4, 3, 3, 2, 1, 1 }
@endcode
You can use letters `x`, `y`, `z`, `w` and `r`, `g`, `b`, `a`. Count of
elements is unlimited, but must be at least one. If the resulting vector is
two, three or four-component, corresponding Vector2, Vector3 or Vector4
specialization is returned.
@attention This function is more convenient to write than
swizzle(const Vector<size, T>&), but unless the result is marked with
`constexpr`, the evaluation of the swizzling operation probably won't be
evaluated at compile time, but at runtime.
@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy()
*/
template<size_t size, class T, size_t newSize> inline constexpr typename Implementation::TypeForSize<newSize-1, T>::Type swizzle(const Vector<size, T>& vector, const char(&components)[newSize]) {
return Implementation::swizzleFrom(typename Implementation::GenerateSequence<newSize-1>::Type(), vector, components);
}
}}
#endif

29
src/Math/Test/SwizzleTest.cpp

@ -30,31 +30,52 @@ typedef Math::Vector4<int> Vector4;
SwizzleTest::SwizzleTest() {
addTests(&SwizzleTest::xyzw,
&SwizzleTest::rgba,
&SwizzleTest::fromSmall,
&SwizzleTest::type,
&SwizzleTest::defaultType);
}
void SwizzleTest::xyzw() {
Vector4 orig(2, 4, 5, 7);
CORRADE_COMPARE((swizzle<'z', 'x', 'w', 'y'>(orig)), Vector4(5, 2, 7, 4));
Vector4 swizzled(5, 2, 7, 4);
CORRADE_COMPARE(swizzle(orig, "zxwy"), swizzled);
CORRADE_COMPARE((swizzle<'z', 'x', 'w', 'y'>(orig)), swizzled);
}
void SwizzleTest::rgba() {
Vector4 orig(2, 4, 5, 7);
CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g'>(orig)), Vector4(5, 2, 7, 4));
Vector4 swizzled(5, 2, 7, 4);
CORRADE_COMPARE(swizzle(orig, "brag"), swizzled);
CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g'>(orig)), swizzled);
}
void SwizzleTest::fromSmall() {
/* Force compile-time evaluation for both */
constexpr Vector2 orig(1, 2);
CORRADE_VERIFY((integral_constant<bool, swizzle(orig, "gxr").x() == 2>::value));
CORRADE_COMPARE((swizzle<'g', 'x', 'r'>(orig)), Vector3(2, 1, 1));
}
void SwizzleTest::type() {
Vector4 orig;
CORRADE_VERIFY((is_same<decltype(swizzle<'y', 'a'>(orig)), Vector2>::value));
CORRADE_VERIFY((is_same<decltype(swizzle(orig, "ya")), Vector2>::value));
CORRADE_VERIFY((is_same<decltype(swizzle<'y', 'z', 'a'>(orig)), Vector3>::value));
CORRADE_VERIFY((is_same<decltype(swizzle(orig, "yza")), Vector3>::value));
CORRADE_VERIFY((is_same<decltype(swizzle<'y', 'a', 'y', 'x'>(orig)), Vector4>::value));
CORRADE_VERIFY((is_same<decltype(swizzle(orig, "yayx")), Vector4>::value));
}
void SwizzleTest::defaultType() {
Vector4 orig(1, 2, 3, 4);
CORRADE_COMPARE(swizzle<'b'>(orig), (Vector<1, int>(3)));
CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g', 'z', 'y', 'x'>(orig)), (Vector<7, int>(3, 1, 4, 2, 3, 2, 1)));
Vector<1, int> b(3);
CORRADE_COMPARE(swizzle<'b'>(orig), b);
CORRADE_COMPARE(swizzle(orig, "b"), b);
Vector<7, int> bragzyx(3, 1, 4, 2, 3, 2, 1);
CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g', 'z', 'y', 'x'>(orig)), bragzyx);
CORRADE_COMPARE(swizzle(orig, "bragzyx"), bragzyx);
}
}}}

1
src/Math/Test/SwizzleTest.h

@ -25,6 +25,7 @@ class SwizzleTest: public Corrade::TestSuite::Tester<SwizzleTest> {
void xyzw();
void rgba();
void fromSmall();
void type();
void defaultType();
};

18
src/Math/Vector.h

@ -26,11 +26,21 @@
namespace Magnum { namespace Math {
/**
@brief %Vector
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<size_t ...> struct Sequence {};
@todo Swizzling
*/
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<size_t N, size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
template<size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
}
#endif
/** @brief %Vector */
template<size_t size, class T> class Vector {
public:
const static size_t Size = size; /**< @brief %Vector size */

Loading…
Cancel
Save