From 079a7be67d15c7f1a770f5e289d31b676e771bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 3 Aug 2012 18:12:55 +0200 Subject: [PATCH 01/11] Disable non-constexpr one-parameter constructor for Vector<1, T>. It was clashing with the default "initializer-list" constructor, which is constexpr. This constructor is also explicit, which makes it impossible to e.g. return Vector<1, T> from function without explicitly specifying name , while for Vector<2, T> it works: return {1, 2}; // works for Vector<2, int> return {1}; // doesn't work for Vector<1, int> --- src/Math/Vector.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Math/Vector.h b/src/Math/Vector.h index d84f312ab..0a56fa479 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -103,7 +103,11 @@ template class Vector { * @brief Constructor * @param value Value for all fields */ + #ifndef DOXYGEN_GENERATING_OUTPUT + template inline explicit Vector(typename std::enable_if::value && size != 1, U>::type value) { + #else inline explicit Vector(T value) { + #endif for(size_t i = 0; i != size; ++i) _data[i] = value; } From fff22d08229fe857a6e31939aeee5e0411e1142a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 3 Aug 2012 18:16:16 +0200 Subject: [PATCH 02/11] New function for vector component swizzling. --- src/Math/Swizzle.h | 77 +++++++++++++++++++++++++++++++++++ src/Math/Test/CMakeLists.txt | 2 + src/Math/Test/SwizzleTest.cpp | 62 ++++++++++++++++++++++++++++ src/Math/Test/SwizzleTest.h | 34 ++++++++++++++++ src/Math/Vector3.h | 2 + src/Math/Vector4.h | 6 +++ 6 files changed, 183 insertions(+) create mode 100644 src/Math/Swizzle.h create mode 100644 src/Math/Test/SwizzleTest.cpp create mode 100644 src/Math/Test/SwizzleTest.h diff --git a/src/Math/Swizzle.h b/src/Math/Swizzle.h new file mode 100644 index 000000000..cfbec9290 --- /dev/null +++ b/src/Math/Swizzle.h @@ -0,0 +1,77 @@ +#ifndef Magnum_Math_Swizzle_h +#define Magnum_Math_Swizzle_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Function Magnum::Math::swizzle() + */ + +#include "Vector4.h" + +namespace Magnum { namespace Math { + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct GetPosition { + static_assert(size > position, "Swizzle parameter out of range of base vector"); + + inline constexpr static size_t value() { return position; } + }; + + template struct GetComponent {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + + template struct TypeForSize { + typedef Vector Type; + }; + + template struct TypeForSize<2, T> { typedef Vector2 Type; }; + template struct TypeForSize<3, T> { typedef Vector3 Type; }; + template struct TypeForSize<4, T> { typedef Vector4 Type; }; +} +#endif + +/** +@brief Swizzle Vector components + +Creates new vector from given components. Example: +@code +Vector4 original(1, 2, 3, 4); + +auto vec = swizzle<'a', 'b', 'b', 'g', 'r', 'r'>(original); +// 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. + +@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy() +*/ +template inline constexpr typename Implementation::TypeForSize::Type swizzle(const Vector& vector) { + return {vector[Implementation::GetComponent::value()]...}; +} + +}} + +#endif diff --git a/src/Math/Test/CMakeLists.txt b/src/Math/Test/CMakeLists.txt index 9c96b0ccb..d19e1d975 100644 --- a/src/Math/Test/CMakeLists.txt +++ b/src/Math/Test/CMakeLists.txt @@ -5,6 +5,8 @@ corrade_add_test2(MathVector2Test Vector2Test.cpp) corrade_add_test2(MathVector3Test Vector3Test.cpp) corrade_add_test2(MathVector4Test Vector4Test.cpp) +corrade_add_test2(MathSwizzleTest SwizzleTest.cpp) + corrade_add_test2(MathMatrixTest MatrixTest.cpp) corrade_add_test2(MathMatrix3Test Matrix3Test.cpp) corrade_add_test2(MathMatrix4Test Matrix4Test.cpp) diff --git a/src/Math/Test/SwizzleTest.cpp b/src/Math/Test/SwizzleTest.cpp new file mode 100644 index 000000000..f71cc8d6d --- /dev/null +++ b/src/Math/Test/SwizzleTest.cpp @@ -0,0 +1,62 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "SwizzleTest.h" + +#include "Swizzle.h" + +using namespace std; + +CORRADE_TEST_MAIN(Magnum::Math::Test::SwizzleTest) + +namespace Magnum { namespace Math { namespace Test { + +typedef Math::Vector2 Vector2; +typedef Math::Vector3 Vector3; +typedef Math::Vector4 Vector4; + +template using Vector = Math::Vector; + +SwizzleTest::SwizzleTest() { + addTests(&SwizzleTest::xyzw, + &SwizzleTest::rgba, + &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)); +} + +void SwizzleTest::rgba() { + Vector4 orig(2, 4, 5, 7); + CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g'>(orig)), Vector4(5, 2, 7, 4)); +} + +void SwizzleTest::type() { + Vector4 orig; + CORRADE_VERIFY((is_same(orig)), Vector2>::value)); + CORRADE_VERIFY((is_same(orig)), Vector3>::value)); + CORRADE_VERIFY((is_same(orig)), Vector4>::value)); +} + +void SwizzleTest::defaultType() { + Vector4 orig(1, 2, 3, 4); + CORRADE_COMPARE(swizzle<'b'>(orig), Vector<1>(3)); + CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g', 'z', 'y', 'x'>(orig)), Vector<7>(3, 1, 4, 2, 3, 2, 1)); +} + +}}} diff --git a/src/Math/Test/SwizzleTest.h b/src/Math/Test/SwizzleTest.h new file mode 100644 index 000000000..f68a05e45 --- /dev/null +++ b/src/Math/Test/SwizzleTest.h @@ -0,0 +1,34 @@ +#ifndef Magnum_Math_Test_SwizzleTest_h +#define Magnum_Math_Test_SwizzleTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace Math { namespace Test { + +class SwizzleTest: public Corrade::TestSuite::Tester { + public: + SwizzleTest(); + + void xyzw(); + void rgba(); + void type(); + void defaultType(); +}; + +}}} + +#endif diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index e9b691914..30072d7f5 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -81,6 +81,8 @@ template class Vector3: public Vector<3, T> { /** * @brief XY part of the vector * @return First two components of the vector + * + * @see swizzle() */ inline constexpr Vector2 xy() const { return Vector2::from(Vector<3, T>::data()); } diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index a447bfac4..c406ef19b 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -70,12 +70,16 @@ template class Vector4: public Vector<4, T> { /** * @brief XYZ part of the vector * @return First three components of the vector + * + * @see swizzle() */ inline constexpr Vector3 xyz() const { return Vector3::from(Vector<4, T>::data()); } /** * @brief XY part of the vector * @return First two components of the vector + * + * @see swizzle() */ inline constexpr Vector2 xy() const { return Vector2::from(Vector<4, T>::data()); } @@ -92,6 +96,8 @@ template class Vector4: public Vector<4, T> { /** * @brief RGB part of the vector * @return First three components of the vector + * + * @see swizzle() */ inline constexpr Vector3 rgb() const { return xyz(); } From cedf9276fac498b5074f126e932ac81c70378695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 3 Aug 2012 18:20:20 +0200 Subject: [PATCH 03/11] Don't install removed Set.h. --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f166b6d5c..2f6fec80f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,7 +53,6 @@ set(Magnum_HEADERS Query.h Renderbuffer.h Scene.h - Set.h Shader.h SizeTraits.h Texture.h From 95c2b05a45fbc97d12be1020867c352041dc7f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 3 Aug 2012 18:27:46 +0200 Subject: [PATCH 04/11] ...and install new Swizzle.h. Damn. --- src/Math/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Math/CMakeLists.txt b/src/Math/CMakeLists.txt index a0cc17b69..d12a6a16c 100644 --- a/src/Math/CMakeLists.txt +++ b/src/Math/CMakeLists.txt @@ -6,6 +6,7 @@ set(MagnumMath_HEADERS Matrix.h Matrix3.h Matrix4.h + Swizzle.h Vector.h Vector2.h Vector3.h From 54f3dc3d99051713a005a1a37586b65512fa71ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 4 Aug 2012 18:07:52 +0200 Subject: [PATCH 05/11] Small cleanup, fixed small typo. --- src/Contexts/EglContext.cpp | 2 +- src/Contexts/Sdl2Context.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index a6f8a842c..7c6f6bbfa 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -73,7 +73,7 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2visual, AllocNone); + attr.colormap = XCreateColormap(xDisplay, root, visInfo->visual, AllocNone); attr.event_mask = StructureNotifyMask|ExposureMask|KeyPressMask; unsigned long mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask; xWindow = XCreateWindow(xDisplay, root, 20, 20, size.x(), size.y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); diff --git a/src/Contexts/Sdl2Context.h b/src/Contexts/Sdl2Context.h index 906daf49a..221a2dccc 100644 --- a/src/Contexts/Sdl2Context.h +++ b/src/Contexts/Sdl2Context.h @@ -100,7 +100,7 @@ class Sdl2Context: public AbstractContext { /** * @brief Key release event - * @param key Key release + * @param key Key released */ virtual void keyReleaseEvent(Key key); From b7df3274666ac92b0507b7692792df30770061c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 4 Aug 2012 18:18:05 +0200 Subject: [PATCH 06/11] EglContext: Show window on exec(), make the context current only once. --- src/Contexts/EglContext.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index 7c6f6bbfa..e3ab85d74 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -98,8 +98,7 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2 Date: Sat, 4 Aug 2012 19:09:45 +0200 Subject: [PATCH 07/11] EglContext: keyboard and mouse handling. --- src/Contexts/EglContext.cpp | 24 +++++++++++ src/Contexts/EglContext.h | 86 +++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index e3ab85d74..e66ff5036 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -17,6 +17,9 @@ #define None 0L // redef Xlib nonsense +/* Mask for X events */ +#define INPUT_MASK KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask + using namespace std; namespace Magnum { namespace Contexts { @@ -98,6 +101,9 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y}); + break; + case KeyRelease: + keyReleaseEvent(static_cast(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y}); + break; + case ButtonPress: + mousePressEvent(static_cast(event.xbutton.button), {event.xbutton.x, event.xbutton.y}); + break; + case ButtonRelease: + mouseReleaseEvent(static_cast(event.xbutton.button), {event.xbutton.x, event.xbutton.y}); + break; + } + } + /** @todo Handle at least window closing and resizing */ drawEvent(); } diff --git a/src/Contexts/EglContext.h b/src/Contexts/EglContext.h index fe2e48cb2..b9c4edb57 100644 --- a/src/Contexts/EglContext.h +++ b/src/Contexts/EglContext.h @@ -62,6 +62,8 @@ class EglContext: public AbstractContext { int exec(); + /** @{ @name Drawing functions */ + protected: /** @copydoc GlutContext::viewportEvent() */ virtual void viewportEvent(const Math::Vector2& size) = 0; @@ -72,6 +74,84 @@ class EglContext: public AbstractContext { /** @copydoc GlutContext::swapBuffers() */ inline void swapBuffers() { eglSwapBuffers(display, surface); } + /*@}*/ + + /** @{ @name Keyboard handling */ + + public: + /** @brief Key */ + enum class Key: KeySym { + Up = XK_Up, /**< Up arrow */ + Down = XK_Down, /**< Down arrow */ + Left = XK_Left, /**< Left arrow */ + Right = XK_Right, /**< Right arrow */ + F1 = XK_F1, /**< F1 */ + F2 = XK_F2, /**< F2 */ + F3 = XK_F3, /**< F3 */ + F4 = XK_F4, /**< F4 */ + F5 = XK_F5, /**< F5 */ + F6 = XK_F6, /**< F6 */ + F7 = XK_F7, /**< F7 */ + F8 = XK_F8, /**< F8 */ + F9 = XK_F9, /**< F9 */ + F10 = XK_F10, /**< F10 */ + F11 = XK_F11, /**< F11 */ + F12 = XK_F12, /**< F12 */ + Home = XK_Home, /**< Home */ + End = XK_End, /**< End */ + PageUp = XK_Page_Up, /**< Page up */ + PageDown = XK_Page_Down /**< Page down */ + }; + + protected: + /** + * @brief Key press event + * @param key Key pressed + * @param position Cursor position + * + * Called when an key is pressed. Default implementation does nothing. + */ + virtual void keyPressEvent(Key key, const Math::Vector2& position) = 0; + + /** + * @brief Key press event + * @param key Key released + * @param position Cursor position + * + * Called when an key is released. Default implementation does nothing. + */ + virtual void keyReleaseEvent(Key key, const Math::Vector2& position) = 0; + + /*@}*/ + + /** @{ @name Mouse handling */ + public: + /** @brief Mouse button */ + enum class MouseButton: unsigned int { + Left = Button1, /**< Left button */ + Middle = Button2, /**< Middle button */ + Right = Button3, /**< Right button */ + WheelUp = Button4, /**< Wheel up */ + WheelDown = Button5 /**< Wheel down */ + }; + + protected: + /** + * @brief Mouse press event + * + * Called when mouse button is pressed. Default implementation does + * nothing. + */ + virtual void mousePressEvent(MouseButton button, const Math::Vector2& position); + + /** + * @brief Mouse release event + * + * Called when mouse button is released. Default implementation does + * nothing. + */ + virtual void mouseReleaseEvent(MouseButton button, const Math::Vector2& position); + private: Display* xDisplay; Window xWindow; @@ -84,6 +164,12 @@ class EglContext: public AbstractContext { Math::Vector2 viewportSize; }; +inline void EglContext::keyPressEvent(EglContext::Key, const Math::Vector2&) {} +inline void EglContext::keyReleaseEvent(EglContext::Key, const Math::Vector2&) {} +inline void EglContext::mousePressEvent(EglContext::MouseButton, const Math::Vector2&) {} +inline void EglContext::mouseReleaseEvent(EglContext::MouseButton, const Math::Vector2&) {} + + }} #endif From d92df0777e02b38b5e14a07e8b0d3910b7f2c16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 4 Aug 2012 19:10:27 +0200 Subject: [PATCH 08/11] EglContext: Not sure what this did, but this doesn't affect anything. Was getting out-of-sync with INPUT_MASK, so setting it to 0. --- src/Contexts/EglContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index e66ff5036..368f1c2d0 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -77,7 +77,7 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2visual, AllocNone); - attr.event_mask = StructureNotifyMask|ExposureMask|KeyPressMask; + attr.event_mask = 0; unsigned long mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask; xWindow = XCreateWindow(xDisplay, root, 20, 20, size.x(), size.y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); XSetStandardProperties(xDisplay, xWindow, title.c_str(), 0, None, 0, 0, 0); From 6c964d703c87a5a15b069c7803eb3d31e07ff504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 4 Aug 2012 19:12:31 +0200 Subject: [PATCH 09/11] EglContext: Handle window resizing. --- src/Contexts/EglContext.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index 368f1c2d0..8aea12c2b 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -18,7 +18,7 @@ #define None 0L // redef Xlib nonsense /* Mask for X events */ -#define INPUT_MASK KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask +#define INPUT_MASK KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask using namespace std; @@ -140,6 +140,16 @@ int EglContext::exec() { XEvent event; while(XCheckWindowEvent(xDisplay, xWindow, INPUT_MASK, &event)) { switch(event.type) { + /* Window resizing */ + case ConfigureNotify: { + Math::Vector2 size(event.xconfigure.width, event.xconfigure.height); + if(size != viewportSize) { + viewportSize = size; + viewportEvent(size); + } + } break; + + /* Key/mouse events */ case KeyPress: keyPressEvent(static_cast(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y}); break; From 9ea8efe73be184b550e7f24898a93f4b922ddc6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 4 Aug 2012 19:12:58 +0200 Subject: [PATCH 10/11] EglContext: Handle window closing. This is the most fucked up way to so fucking simple thing. --- src/Contexts/EglContext.cpp | 11 +++++++++++ src/Contexts/EglContext.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index 8aea12c2b..b05890ab8 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -83,6 +83,10 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2 Date: Sat, 4 Aug 2012 19:55:31 +0200 Subject: [PATCH 11/11] FindMagnum: don't expose internal ${COMPONENT}_INCLUDE_DIR to users. --- modules/FindMagnum.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index ed6c4d45e..09a41585c 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -147,6 +147,9 @@ foreach(component ${Magnum_FIND_COMPONENTS}) find_path(_MAGNUM_${_COMPONENT}_INCLUDE_DIR NAMES ${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES} PATHS ${MAGNUM_INCLUDE_DIR}/${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX}) + + # Don't expose this variable to end users + mark_as_advanced(FORCE _MAGNUM_${_COMPONENT}_INCLUDE_DIR) endif() # Decide if the library was found