1 /* This file is part of Dilay 2 * Copyright © 2015-2018 Alexander Bau 3 * Use and redistribute under the terms of the GNU General Public License 4 */ 5 #ifndef DILAY_UTIL 6 #define DILAY_UTIL 7 8 #include <algorithm> 9 #include <functional> 10 #include <glm/fwd.hpp> 11 #include <limits> 12 #include <locale> 13 #include <vector> 14 #include "log.hpp" 15 16 #define DILAY_INFO(fmt, ...) Log::log (Log::Level::Info, __FILE__, __LINE__, fmt, ##__VA_ARGS__); 17 #define DILAY_WARN(fmt, ...) Log::log (Log::Level::Warning, __FILE__, __LINE__, fmt, ##__VA_ARGS__); 18 #define DILAY_PANIC(fmt, ...) \ 19 { \ 20 Log::log (Log::Level::Panic, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \ 21 Log::log (Log::Level::Panic, __FILE__, __LINE__, "aborting due to previous error..."); \ 22 std::abort (); \ 23 } 24 #define DILAY_IMPOSSIBLE DILAY_PANIC ("the impossible happend") 25 26 #define unused(x) ((void) (x)) 27 28 typedef std::pair<unsigned int, unsigned int> ui_pair; 29 30 namespace Util 31 { 32 glm::vec3 midpoint (const glm::vec3&, const glm::vec3&); 33 glm::vec3 transformPosition (const glm::mat4x4&, const glm::vec3&); 34 glm::vec3 transformDirection (const glm::mat4x4&, const glm::vec3&); 35 glm::vec3 orthogonal (const glm::vec3&); 36 glm::ivec2 orthogonalRight (const glm::ivec2&); 37 glm::mat4x4 rotation (const glm::vec3&, const glm::vec3&, float); 38 bool colinear (const glm::vec2&, const glm::vec2&); 39 bool colinear (const glm::vec3&, const glm::vec3&); 40 bool colinearUnit (const glm::vec2&, const glm::vec2&); 41 bool colinearUnit (const glm::vec3&, const glm::vec3&); 42 float smoothStep (const glm::vec3&, const glm::vec3&, float, float); 43 float linearStep (const glm::vec3&, const glm::vec3&, float, float); 44 float cross (const glm::vec2&, const glm::vec2&); 45 std::string readFile (const std::string&); 46 unsigned int solveQuadraticEq (float, float, float, float&, float&); 47 unsigned int solveCubicEq (float, float, float, float&, float&, float&); 48 unsigned int solveCubicEq (float, float, float, float, float&, float&, float&); 49 bool isNaN (float); 50 bool isNaN (const glm::vec3&); 51 bool isNotNull (const glm::vec3&); 52 bool almostEqual (float, float); 53 void warn (const char*, unsigned int, const char*, ...); 54 bool fromString (const std::string&, int&); 55 bool fromString (const std::string&, unsigned int&); 56 bool fromString (const std::string&, float&); 57 unsigned int countOnes (unsigned int); 58 bool hasSuffix (const std::string&, const std::string&); 59 epsilon()60 constexpr float epsilon () { return 0.0001f; } 61 minFloat()62 constexpr float minFloat () { return std::numeric_limits<float>::lowest (); } 63 maxFloat()64 constexpr float maxFloat () { return std::numeric_limits<float>::max (); } 65 minInt()66 constexpr int minInt () { return std::numeric_limits<int>::lowest (); } 67 maxInt()68 constexpr int maxInt () { return std::numeric_limits<int>::max (); } 69 maxUnsignedInt()70 constexpr int maxUnsignedInt () { return std::numeric_limits<unsigned int>::max (); } 71 invalidIndex()72 constexpr unsigned int invalidIndex () { return std::numeric_limits<unsigned int>::max (); } 73 setIfNotNull(T * ptr,const T & value)74 template <typename T> void setIfNotNull (T* ptr, const T& value) 75 { 76 if (ptr) 77 { 78 *ptr = value; 79 } 80 } 81 findIndexByReference(const std::vector<T> & vec,const T & obj)82 template <typename T> unsigned int findIndexByReference (const std::vector<T>& vec, const T& obj) 83 { 84 return &obj - &vec.at (0); 85 } 86 withCLocale(const std::function<T ()> & f)87 template <typename T> T withCLocale (const std::function<T ()>& f) 88 { 89 const std::locale prev = std::locale::global (std::locale::classic ()); 90 T result = f (); 91 std::locale::global (prev); 92 return result; 93 } 94 template <> void withCLocale (const std::function<void()>& f); 95 96 template <typename T> prune(std::vector<T> & v,const std::function<bool (const T &)> & p,std::vector<unsigned int> * indexMap=nullptr)97 void prune (std::vector<T>& v, const std::function<bool(const T&)>& p, 98 std::vector<unsigned int>* indexMap = nullptr) 99 { 100 if (indexMap) 101 { 102 indexMap->resize (v.size (), Util::invalidIndex ()); 103 } 104 auto lastIt = std::find_if_not (v.rbegin (), v.rend (), p); 105 106 if (lastIt == v.rend ()) 107 { 108 v.clear (); 109 } 110 else 111 { 112 unsigned int last = v.size () - (lastIt - v.rbegin ()) - 1; 113 114 for (unsigned int i = 0; i <= last; i++) 115 { 116 if (p (v[i])) 117 { 118 v[i] = v[last]; 119 120 if (indexMap) 121 { 122 (*indexMap)[i] = Util::invalidIndex (); 123 (*indexMap)[last] = i; 124 } 125 126 do 127 { 128 last--; 129 } while (p (v[last])); 130 } 131 else 132 { 133 if (indexMap) 134 { 135 (*indexMap)[i] = i; 136 } 137 } 138 } 139 v.resize (last + 1); 140 } 141 } 142 } 143 144 #endif 145