#pragma once #include "Utils.h" #include "Isaac.h" #include "Curves.h" #define CURVE_POINTS 5 /// /// Curves class. /// namespace EmberNs { /// /// The b-spline curves used to adjust the colors during final accumulation. /// This functionality was gotten inferred from Chaotica. /// Note this is now incompatible with Apophysis, which uses Bezier curves instead. /// template class EMBER_API Curves { public: /// /// Constructor which sets the curve and weight values to their defaults. /// Curves(bool init = false) { if (init) Init(); else Clear(); } /// /// Default copy constructor. /// /// The Curves object to copy Curves(const Curves& curves) { Curves::operator=(curves); } /// /// Copy constructor to copy a Curves object of type U. /// Special case that must be here in the header because it has /// a second template parameter. /// /// The Curves object to copy template Curves(const Curves& curves) { Curves::operator=(curves); } /// /// Default assignment operator. /// /// The Curves object to copy Curves& operator = (const Curves& curves) { if (this != &curves) Curves::operator=(curves); return *this; } /// /// Assignment operator to assign a Curves object of type U. /// /// The Curves object to copy /// Reference to updated self template Curves& operator = (const Curves& curves) { int i = 0; for (auto& pp : curves.m_Points) { int j = 0; m_Points[i].clear(); for (auto& p : pp) { m_Points[i].push_back(p); j++; } i++; } i = 0; return *this; } /// /// Unary addition operator to add a Curves object to this one. /// /// The Curves object to add /// Reference to updated self template Curves& operator += (const Curves& curves) { int i = 0; for (auto& pp : m_Points) { int j = 0; for (auto& p : pp) { if (j < curves.m_Points[i].size()) p += curves.m_Points[i][j]; else break; j++; } i++; } return *this; } /// /// Unary multiplication operator to multiply this object by another Curves object. /// /// The Curves object to multiply this one by /// Reference to updated self template Curves& operator *= (const Curves& curves) { int i = 0; for (auto& pp : m_Points) { int j = 0; for (auto& p : pp) { if (j < curves.m_Points[i].size()) p *= curves.m_Points[i][j]; else break; j++; } i++; } return *this; } /// /// Unary multiplication operator to multiply this object by a scalar of type T. /// /// The scalar to multiply this object by /// Reference to updated self template Curves& operator *= (const U& t) { for (auto& pp : m_Points) for (auto& p : pp) p *= T(t); return *this; } /// /// Set the curve and weight values to their default state. /// void Init() { for (size_t i = 0; i < 4; i++) Init(i); } /// /// Set a specific curve and its weight value to their default state. /// void Init(size_t i) { if (i < 4) { m_Points[i].resize(5); m_Points[i][0] = v2T(0); m_Points[i][1] = v2T(T(0.25)); m_Points[i][2] = v2T(T(0.50)); m_Points[i][3] = v2T(T(0.75)); m_Points[i][4] = v2T(1); } } /// /// Set the curve and weight values to an empty state. /// void Clear() { for (auto& p : m_Points) p.clear(); } /// /// Whether any points are not the default. /// /// True if any point has been set to a value other than the default, else false. bool CurvesSet() { bool set = false; for (size_t i = 0; i < 4; i++) { if (m_Points[i].size() != CURVE_POINTS) { set = true; break; } if ((m_Points[i][0] != v2T(0)) || (m_Points[i][1] != v2T(T(0.25))) || (m_Points[i][2] != v2T(T(0.50))) || (m_Points[i][3] != v2T(T(0.75))) || (m_Points[i][4] != v2T(1)) ) { set = true; break; } } return set; } public: std::array, 4> m_Points; }; //Must declare this outside of the class to provide for both orders of parameters. /// /// Multiplication operator to multiply a Curves object by a scalar of type U. /// /// The curves object to multiply /// The scalar to multiply curves by by /// Copy of new Curves template Curves operator * (const Curves& curves, const U& t) { T tt = T(t); Curves c(curves); for (auto& pp : c.m_Points) for (auto& p : pp) p *= tt; return c; } /// /// Multiplication operator for reverse order. /// /// The scalar to multiply curves by by /// The curves object to multiply /// Copy of new Curves template Curves operator * (const U& t, const Curves& curves) { return curves * t; } }