2022-10-20 11:30:15 -04:00
|
|
|
/*
|
|
|
|
* Created by Brett Terpstra 6920201 on 14/10/22.
|
|
|
|
* Copyright (c) Brett Terpstra 2022 All Rights Reserved
|
|
|
|
*
|
|
|
|
* This file is used to include common standard library headers
|
|
|
|
* There are some things {String, Maps} that I use a lot
|
|
|
|
* Plus common defines that might be useful in the future.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef STEP_2_STD_H
|
|
|
|
#define STEP_2_STD_H
|
|
|
|
|
|
|
|
/**
|
|
|
|
* includes
|
|
|
|
*/
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <vector>
|
2022-10-23 23:46:12 -04:00
|
|
|
#include "logging.h"
|
2022-10-20 11:30:15 -04:00
|
|
|
#include <string>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cctype>
|
|
|
|
#include <locale>
|
|
|
|
#include <sstream>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <limits>
|
|
|
|
#include <random>
|
2022-11-13 13:03:48 -05:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <memory>
|
2022-10-20 11:30:15 -04:00
|
|
|
|
2022-11-13 14:13:14 -05:00
|
|
|
#define RTAssert(condition) static_cast <bool> (condition) ? void(0) : throw std::runtime_error("Assert Failed!");
|
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
/**
|
|
|
|
* defines
|
|
|
|
*/
|
|
|
|
#define RAYTRACING_VERSION_MAJOR 0
|
|
|
|
#define RAYTRACING_VERSION_MINOR 0
|
|
|
|
#define RAYTRACING_VERSION_PATCH 1
|
|
|
|
#define RAYTRACING_VERSION_STRING "0.0.1"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constants
|
|
|
|
*/
|
|
|
|
const double infinity = std::numeric_limits<double>::infinity();
|
|
|
|
const double ninfinity = -std::numeric_limits<double>::infinity();
|
|
|
|
// PI, to a large # of digits
|
|
|
|
const double PI = 3.1415926535897932385;
|
|
|
|
// very small number
|
|
|
|
const double EPSILON = 0.0000001;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* classes
|
|
|
|
*/
|
2022-11-13 13:03:48 -05:00
|
|
|
static inline double degreeeToRadian(double deg) {
|
|
|
|
return deg * PI / 180.0;
|
2022-10-20 11:30:15 -04:00
|
|
|
}
|
|
|
|
|
2022-12-12 15:47:56 -05:00
|
|
|
constexpr unsigned long GLOBAL_SEED = 691l * 691l * 691l;
|
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
namespace Raytracing {
|
2022-11-16 17:49:02 -05:00
|
|
|
struct Signals {
|
2022-12-12 15:47:56 -05:00
|
|
|
bool haltExecution{false};
|
|
|
|
bool pauseRaytracing{false};
|
|
|
|
bool haltRaytracing{false};
|
2022-11-16 17:49:02 -05:00
|
|
|
};
|
2022-12-12 15:47:56 -05:00
|
|
|
|
2022-11-13 13:03:48 -05:00
|
|
|
class AlignedAllocator {
|
|
|
|
private:
|
|
|
|
public:
|
|
|
|
// not sure if this actually provides a performance benefit. Testing is inconclusive
|
|
|
|
template<typename T>
|
|
|
|
static T* allocateCacheAligned(int number = 1) {
|
|
|
|
void* allocatedSpace = aligned_alloc(64, sizeof(T) * number);
|
|
|
|
return new(allocatedSpace) T[number];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
class Random {
|
|
|
|
private:
|
|
|
|
std::random_device rd; // obtain a random number from hardware
|
|
|
|
std::mt19937 gen;
|
2022-11-13 13:03:48 -05:00
|
|
|
std::uniform_real_distribution<double> doubleDistr{0, 1};
|
2022-11-22 00:26:23 -05:00
|
|
|
std::uniform_int_distribution<long> longDistr{0, 1};
|
|
|
|
std::uniform_int_distribution<unsigned long> ulongDistr{0, 1};
|
2022-10-20 11:30:15 -04:00
|
|
|
public:
|
2022-12-12 15:47:56 -05:00
|
|
|
Random():
|
|
|
|
gen(std::mt19937(GLOBAL_SEED)) {}
|
|
|
|
|
|
|
|
Random(double min, double max):
|
|
|
|
gen(std::mt19937(GLOBAL_SEED)), doubleDistr{min, max}, longDistr{(long) min, (long) max},
|
|
|
|
ulongDistr{(unsigned long) min, (unsigned long) max} {}
|
|
|
|
|
|
|
|
Random(long min, long max):
|
|
|
|
gen(std::mt19937(GLOBAL_SEED)), doubleDistr{(double) min, (double) max}, longDistr{(long) min, (long) max},
|
|
|
|
ulongDistr{(unsigned long) min, (unsigned long) max} {}
|
|
|
|
|
|
|
|
Random(unsigned long min, unsigned long max):
|
|
|
|
gen(std::mt19937(GLOBAL_SEED)), doubleDistr{(double) min, (double) max}, longDistr{(long) min, (long) max},
|
|
|
|
ulongDistr{(unsigned long) min, (unsigned long) max} {}
|
|
|
|
|
2022-11-13 13:03:48 -05:00
|
|
|
double getDouble() {
|
2022-10-20 11:30:15 -04:00
|
|
|
return doubleDistr(gen);
|
|
|
|
}
|
2022-12-12 15:47:56 -05:00
|
|
|
|
|
|
|
long getLong() {
|
2022-11-22 00:26:23 -05:00
|
|
|
return longDistr(gen);
|
|
|
|
}
|
2022-12-12 15:47:56 -05:00
|
|
|
|
|
|
|
unsigned long getULong() {
|
2022-11-22 00:26:23 -05:00
|
|
|
return ulongDistr(gen);
|
|
|
|
}
|
2022-10-20 11:30:15 -04:00
|
|
|
};
|
2022-11-13 13:03:48 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
class String {
|
|
|
|
public:
|
2022-12-13 01:33:31 -05:00
|
|
|
/**
|
|
|
|
* Converts the string into lower case
|
|
|
|
* @param s string to lower case
|
|
|
|
* @return a string copy that is all lower case
|
|
|
|
*/
|
2022-11-13 13:03:48 -05:00
|
|
|
static inline std::string toLowerCase(const std::string& s) {
|
2022-10-20 11:30:15 -04:00
|
|
|
std::stringstream str;
|
2022-12-12 15:47:56 -05:00
|
|
|
std::for_each(
|
|
|
|
s.begin(), s.end(), [&str](unsigned char ch) {
|
|
|
|
str << (char) std::tolower(ch);
|
|
|
|
}
|
|
|
|
);
|
2022-10-20 11:30:15 -04:00
|
|
|
return str.str();
|
|
|
|
}
|
2022-12-12 15:47:56 -05:00
|
|
|
|
2022-12-13 01:33:31 -05:00
|
|
|
/**
|
|
|
|
* Converts the string into upper case
|
|
|
|
* @param s string to upper case
|
|
|
|
* @return a string copy that is all upper case
|
|
|
|
*/
|
2022-11-13 13:03:48 -05:00
|
|
|
static inline std::string toUpperCase(const std::string& s) {
|
2022-10-20 11:30:15 -04:00
|
|
|
std::stringstream str;
|
2022-12-12 15:47:56 -05:00
|
|
|
std::for_each(
|
|
|
|
s.begin(), s.end(), [&str](unsigned char ch) {
|
|
|
|
str << (char) std::toupper(ch);
|
|
|
|
}
|
|
|
|
);
|
2022-10-20 11:30:15 -04:00
|
|
|
return str.str();
|
|
|
|
}
|
2022-12-12 15:47:56 -05:00
|
|
|
|
2022-12-13 01:33:31 -05:00
|
|
|
/**
|
|
|
|
* @return the standard string of time.now
|
|
|
|
*/
|
2022-12-12 15:47:56 -05:00
|
|
|
static inline std::string getTimeString() {
|
|
|
|
auto t = std::time(nullptr);
|
|
|
|
auto now = std::localtime(&t);
|
|
|
|
std::stringstream timeString;
|
|
|
|
timeString << (1900 + now->tm_year);
|
|
|
|
timeString << "-";
|
|
|
|
timeString << (1 + now->tm_mon);
|
|
|
|
timeString << "-";
|
|
|
|
timeString << now->tm_mday;
|
|
|
|
timeString << " ";
|
|
|
|
timeString << now->tm_hour;
|
|
|
|
timeString << ":";
|
|
|
|
timeString << now->tm_min;
|
|
|
|
timeString << ":";
|
|
|
|
timeString << now->tm_sec;
|
|
|
|
return timeString.str();
|
|
|
|
}
|
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
|
|
|
|
// extended to return a vector
|
2022-11-13 13:03:48 -05:00
|
|
|
static inline std::vector<std::string> split(std::string s, const std::string& delim) {
|
2022-10-20 11:30:15 -04:00
|
|
|
size_t pos = 0;
|
|
|
|
std::vector<std::string> tokens;
|
|
|
|
while ((pos = s.find(delim)) != std::string::npos) {
|
|
|
|
auto token = s.substr(0, pos);
|
|
|
|
tokens.push_back(token);
|
|
|
|
s.erase(0, pos + delim.length());
|
|
|
|
}
|
|
|
|
tokens.push_back(s);
|
|
|
|
return tokens;
|
|
|
|
}
|
2022-12-12 15:47:56 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// taken from https://stackoverflow.com/questions/216823/how-to-trim-an-stdstring
|
|
|
|
// would've preferred to use boost lib but instructions said to avoid external libs
|
|
|
|
// trim from start (in place)
|
|
|
|
static inline std::string& ltrim(std::string& s) {
|
2022-12-12 15:47:56 -05:00
|
|
|
s.erase(
|
|
|
|
s.begin(), std::find_if(
|
|
|
|
s.begin(), s.end(), [](unsigned char ch) {
|
|
|
|
return !std::isspace(ch);
|
|
|
|
}
|
|
|
|
));
|
2022-10-20 11:30:15 -04:00
|
|
|
return s;
|
|
|
|
}
|
2022-11-13 13:03:48 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// trim from end (in place)
|
|
|
|
static inline std::string& rtrim(std::string& s) {
|
2022-12-12 15:47:56 -05:00
|
|
|
s.erase(
|
|
|
|
std::find_if(
|
|
|
|
s.rbegin(), s.rend(), [](unsigned char ch) {
|
|
|
|
return !std::isspace(ch);
|
|
|
|
}
|
|
|
|
).base(), s.end());
|
2022-10-20 11:30:15 -04:00
|
|
|
return s;
|
|
|
|
}
|
2022-11-13 13:03:48 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// trim from both ends (in place)
|
|
|
|
static inline std::string& trim(std::string& s) {
|
|
|
|
ltrim(s);
|
|
|
|
rtrim(s);
|
|
|
|
return s;
|
|
|
|
}
|
2022-11-13 13:03:48 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// trim from start (copying)
|
|
|
|
static inline std::string ltrim_copy(std::string s) {
|
|
|
|
ltrim(s);
|
|
|
|
return s;
|
|
|
|
}
|
2022-11-13 13:03:48 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// trim from end (copying)
|
|
|
|
static inline std::string rtrim_copy(std::string s) {
|
|
|
|
rtrim(s);
|
|
|
|
return s;
|
|
|
|
}
|
2022-11-13 13:03:48 -05:00
|
|
|
|
2022-10-20 11:30:15 -04:00
|
|
|
// trim from both ends (copying)
|
|
|
|
static inline std::string trim_copy(std::string s) {
|
|
|
|
trim(s);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-13 13:03:48 -05:00
|
|
|
static Raytracing::Random rnd{};
|
2022-10-20 11:30:15 -04:00
|
|
|
|
2022-11-13 13:03:48 -05:00
|
|
|
static inline double getRandomDouble() {
|
2022-10-20 11:30:15 -04:00
|
|
|
return rnd.getDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline double clamp(double val, double min, double max) {
|
|
|
|
if (val < min)
|
|
|
|
return min;
|
|
|
|
if (val > max)
|
|
|
|
return max;
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif //STEP_2_STD_H
|