MobileRT  1.0
A multi platform C++ CPU progressive Ray Tracer.
Utils.hpp
Go to the documentation of this file.
1 #ifndef MOBILERT_UTILS_UTILS_HPP
2 #define MOBILERT_UTILS_UTILS_HPP
3 
4 #include "Utils_dependent.hpp"
5 
6 #include <algorithm>
7 #include <array>
8 #include <boost/assert.hpp>
9 #include <chrono>
10 #include <cmath>
11 #include <glm/ext.hpp>
12 #include <glm/glm.hpp>
13 
14 #define GLM_ENABLE_EXPERIMENTAL
15 #include <glm/gtx/string_cast.hpp>
16 
17 #include <pcg_random.hpp>
18 #include <random>
19 #include <string>
20 #include <sstream>
21 #include <thread>
22 #include <vector>
23 
24 namespace MobileRT {
25 
26 #ifndef NDEBUG
27 
30  #define LOG_DEBUG(...) \
31  ::Dependent::printDebug( \
32  ::MobileRT::convertToString(::MobileRT::getFileName(__FILE__), ":", __LINE__, ": ", __VA_ARGS__) \
33  )
34 #else
35 
40  #define LOG_DEBUG(...) do { } while (false)
41 #endif
42 
43 #define LOG_INFO(...) \
44  ::Dependent::printInfo( \
45  ::MobileRT::convertToString(::MobileRT::getFileName(__FILE__), ":", __LINE__, ": ", __VA_ARGS__) \
46  )
47 
48 #define LOG_WARN(...) \
49  ::Dependent::printWarn( \
50  ::MobileRT::convertToString(::MobileRT::getFileName(__FILE__), ":", __LINE__, ": ", __VA_ARGS__) \
51  )
52 
53 #define LOG_ERROR(...) \
54  ::Dependent::printError( \
55  ::MobileRT::convertToString(::MobileRT::getFileName(__FILE__), ":", __LINE__, ": ", __VA_ARGS__) \
56  )
57 
58 
59 #ifndef LOG_DEBUG
60 #define LOG_DEBUG(...)
61 #endif
62 
63 #ifndef LOG_INFO
64 #define LOG_INFO(...)
65 #endif
66 
67 #ifndef LOG_WARN
68 #define LOG_WARN(...)
69 #endif
70 
71 #ifndef LOG_ERROR
72 #define LOG_ERROR(...)
73 #endif
74 
75  template<typename T, ::std::size_t S>
76  void fillArrayWithHaltonSeq(::std::array<T, S> *values);
77 
78  template<typename T, ::std::size_t S>
79  void fillArrayWithMersenneTwister(::std::array<T, S> *values);
80 
81  template<typename T, ::std::size_t S>
82  void fillArrayWithPCG(::std::array<T, S> *values);
83 
84  inline ::std::string getFileName(const char *filepath);
85 
86 
87  ::std::int32_t roundDownToMultipleOf(::std::int32_t value, ::std::int32_t multiple);
88 
89  float haltonSequence(::std::uint32_t index, ::std::uint32_t base);
90 
91  ::std::int32_t incrementalAvg(const ::glm::vec3 &sample,
92  ::std::int32_t avg,
93  ::std::int32_t numSample);
94 
95  template<::std::int32_t S, typename T>
96  inline ::std::array<T, S> toArray(const char *values);
97 
98  ::glm::vec2 toVec2(const char *values);
99 
100  ::glm::vec3 toVec3(const char *values);
101 
102  ::glm::vec3 toVec3(const float *values);
103 
104  bool equal(float a, float b);
105 
106  bool equal(const ::glm::vec3 &vec1, const ::glm::vec3 &vec2);
107 
108  template<::std::int32_t S, typename T>
109  bool isValid(const ::glm::vec<S, T> &value);
110 
111  template<::std::int32_t S, typename T>
112  bool hasPositiveValue(const ::glm::vec<S, T> &value);
113 
114  bool isValid(float value);
115 
116  ::glm::vec2 normalize(const ::glm::vec2 &textureCoordinates);
117 
118  ::glm::vec3 normalize(const ::glm::vec3 &color);
119 
120  float fresnel(const ::glm::vec3 &I, const ::glm::vec3 &N, float ior);
121 
122  void checkSystemError(const char *message);
123 
124  void printFreeMemory();
125 
134  template<::std::int32_t S, typename T>
135  void addToStringStream(::std::ostringstream *oss, const ::glm::vec<S, T>& parameter) {
136  *oss << ::glm::to_string(parameter);
137  }
138 
146  template <typename Type>
147  void addToStringStream(::std::ostringstream *oss, const Type& parameter) {
148  *oss << parameter;
149  }
150 
160  template <typename First, typename... Args>
161  void addToStringStream(::std::ostringstream *oss, const First& parameter, Args &&... args) {
162  addToStringStream(oss, parameter);
163  addToStringStream(oss, args...);
164  }
165 
173  template <typename... Args>
174  ::std::string convertToString(Args &&... args) {
175  ::std::ostringstream oss {""};
176  addToStringStream(&oss, args...);
177  oss << '\n';
178  const ::std::string &line {oss.str()};
179  return line;
180  }
181 
188  ::std::string getFileName(const char *const filepath) {
189  const ::std::string &filePath {filepath};
190  ::std::string::size_type filePos {filePath.rfind('/')};
191  if (filePos != ::std::string::npos) {
192  ++filePos;
193  } else {
194  filePos = 0;
195  }
196  const ::std::string &res {filePath.substr(filePos)};
197  return res;
198  }
199 
209  template<typename T, ::std::size_t S>
210  void fillArrayWithHaltonSeq(::std::array<T, S> *const values) {
211  for (typename ::std::array<T, S>::iterator itValues {values->begin()}; itValues < values->end(); ::std::advance(itValues, 1)) {
212  const ::std::uint32_t index {static_cast<::std::uint32_t> (::std::distance(values->begin(), itValues))};
213  *itValues = ::MobileRT::haltonSequence(index, 2);
214  }
215  static ::std::random_device randomDevice {};
216  static ::std::mt19937 generator {randomDevice()};
217  ::std::shuffle(values->begin(), values->end(), generator);
218  }
219 
229  template<typename T, ::std::size_t S>
230  void fillArrayWithMersenneTwister(::std::array<T, S> *const values) {
231  static ::std::uniform_real_distribution<float> uniformDist {0.0F, 1.0F};
232  static ::std::random_device randomDevice {};
233  static ::std::mt19937 generator {randomDevice()};
234  ::std::generate(values->begin(), values->end(), []() {return uniformDist(generator);});
235  }
236 
246  template<typename T, ::std::size_t S>
247  void fillArrayWithPCG(::std::array<T, S> *const values) {
248  static ::pcg_extras::seed_seq_from<::std::random_device> seedSource {};
249  static ::pcg32 generator(seedSource);
250  static ::std::uniform_real_distribution<float> uniformDist {0.0F, 1.0F};
251  ::std::generate(values->begin(), values->end(), []() {return uniformDist(generator);});
252  }
253 
262  template<::std::int32_t S, typename T>
263  bool isValid(const ::glm::vec<S, T> &value) {
264  const bool isNaN {::glm::all(::glm::isnan(value))};
265  const bool isInf {::glm::all(::glm::isinf(value))};
266  const bool res {!isNaN && !isInf};
267  return res;
268  }
269 
278  template<::std::int32_t S, typename T>
279  bool hasPositiveValue(const ::glm::vec<S, T> &value) {
280  return ::glm::any(::glm::greaterThan(value, ::glm::vec<S, T> {0}));
281  }
282 
291  template<::std::int32_t S, typename T>
292  inline ::std::array<T, S> toArray(const char *const values) {
293  ::std::stringstream data {values};
294  ::std::array<float, S> parsedValues {};
295  for (::std::uint32_t i {0u}; i < S; ++i) {
296  data >> parsedValues[i];
297  }
298  return parsedValues;
299  }
300 
301 
302  #ifndef NDEBUG
303 
308  #define ASSERT(condition, ...) \
309  do { \
310  if (!(condition)) { \
311  LOG_DEBUG("Assertion '", #condition, "': ", __VA_ARGS__); \
312  BOOST_ASSERT_MSG(condition, ::MobileRT::convertToString(__VA_ARGS__).c_str()); \
313  } \
314  } while (false)
315  #else
316 
321  #define ASSERT(condition, ...) do { } while (false)
322  #endif
323 
324 
325  namespace std {
334  #if __cplusplus < 201402L
335 
344  template<typename T, typename... Args>
345  ::std::unique_ptr<T> make_unique(Args &&... args) {
346  return ::std::unique_ptr<T>(new T(::std::forward<Args>(args)...));
347  }
348  #else
349 
358  template<typename T, typename... Args>
359  ::std::unique_ptr<T> make_unique(Args &&... args) {
360  return ::std::make_unique<T>(::std::forward<Args>(args)...);
361  }
362  #endif
363 
364  /*
365  * Its necessary to force a C++ version that is not set in the CMakeLists
366  * because with older NDKs, it supports C++11 but this std::to_string is
367  * not implemented there.
368  */
369  #if __cplusplus < 201703L
370 
378  template <typename T> ::std::string to_string(const T& str) {
379  ::std::ostringstream stm {""};
380  stm << str ;
381  return stm.str() ;
382  }
383  #else
384 
391  template <typename T> ::std::string to_string(const T& str) {
393  }
394  #endif
395  }//namespace std
396 
397 
398 }//namespace MobileRT
399 
400 #endif //MOBILERT_UTILS_UTILS_HPP
void fillArrayWithMersenneTwister(::std::array< T, S > *values)
Definition: Utils.hpp:230
void checkSystemError(const char *const message)
Definition: Utils.cpp:237
::std::int32_t roundDownToMultipleOf(const ::std::int32_t value, const ::std::int32_t multiple)
Definition: Utils.cpp:26
::std::string convertToString(Args &&... args)
Definition: Utils.hpp:174
float haltonSequence(::std::uint32_t index, const ::std::uint32_t base)
Definition: Utils.cpp:43
STL namespace.
bool hasPositiveValue(const ::glm::vec< S, T > &value)
Definition: Utils.hpp:279
::std::unique_ptr< T > make_unique(Args &&... args)
Definition: Utils.hpp:345
::std::int32_t incrementalAvg(const ::glm::vec3 &sample, const ::std::int32_t avg, const ::std::int32_t numSample)
Definition: Utils.cpp:66
::glm::vec3 toVec3(const char *const values)
Definition: Utils.cpp:109
inline ::std::string getFileName(const char *filepath)
Definition: Utils.hpp:188
void printFreeMemory()
Definition: Utils.cpp:285
bool equal(const float a, const float b)
Definition: Utils.cpp:133
void fillArrayWithPCG(::std::array< T, S > *values)
Definition: Utils.hpp:247
::std::string to_string(const T &str)
Definition: Utils.hpp:378
float fresnel(const ::glm::vec3 &I, const ::glm::vec3 &N, const float ior)
Definition: Utils.cpp:206
bool isValid(const float value)
Definition: Utils.cpp:163
::glm::vec2 normalize(const ::glm::vec2 &textureCoordinates)
Definition: Utils.cpp:177
::glm::vec2 toVec2(const char *const values)
Definition: Utils.cpp:98
void fillArrayWithHaltonSeq(::std::array< T, S > *values)
Definition: Utils.hpp:210
inline ::std::array< T, S > toArray(const char *values)
Definition: Utils.hpp:292
void addToStringStream(::std::ostringstream *oss, const ::glm::vec< S, T > &parameter)
Definition: Utils.hpp:135
Definition: AABB.cpp:105