mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-22 05:30:06 -05:00
e3e5120130
-Sequence generation was generating the wrong color curves when a non-default curve had less than 5 nodes in it.
274 lines
5.5 KiB
C++
274 lines
5.5 KiB
C++
#pragma once
|
|
|
|
#include "Utils.h"
|
|
#include "Isaac.h"
|
|
#include "Curves.h"
|
|
|
|
#define CURVE_POINTS 5
|
|
|
|
/// <summary>
|
|
/// Curves class.
|
|
/// </summary>
|
|
|
|
namespace EmberNs
|
|
{
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
template <typename T>
|
|
class EMBER_API Curves
|
|
{
|
|
public:
|
|
/// <summary>
|
|
/// Constructor which sets the curve and weight values to their defaults.
|
|
/// </summary>
|
|
Curves(bool init = false)
|
|
{
|
|
if (init)
|
|
Init();
|
|
else
|
|
Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default copy constructor.
|
|
/// </summary>
|
|
/// <param name="curves">The Curves object to copy</param>
|
|
Curves(const Curves<T>& curves)
|
|
{
|
|
Curves<T>::operator=<T>(curves);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="curves">The Curves object to copy</param>
|
|
template <typename U>
|
|
Curves(const Curves<U>& curves)
|
|
{
|
|
Curves<T>::operator=<U>(curves);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default assignment operator.
|
|
/// </summary>
|
|
/// <param name="curves">The Curves object to copy</param>
|
|
Curves<T>& operator = (const Curves<T>& curves)
|
|
{
|
|
if (this != &curves)
|
|
Curves<T>::operator=<T>(curves);
|
|
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Assignment operator to assign a Curves object of type U.
|
|
/// </summary>
|
|
/// <param name="curves">The Curves object to copy</param>
|
|
/// <returns>Reference to updated self</returns>
|
|
template <typename U>
|
|
Curves<T>& operator = (const Curves<U>& 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unary addition operator to add a Curves<T> object to this one.
|
|
/// </summary>
|
|
/// <param name="curves">The Curves object to add</param>
|
|
/// <returns>Reference to updated self</returns>
|
|
template <typename U>
|
|
Curves<T>& operator += (const Curves<U>& 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unary multiplication operator to multiply this object by another Curves<T> object.
|
|
/// </summary>
|
|
/// <param name="curves">The Curves object to multiply this one by</param>
|
|
/// <returns>Reference to updated self</returns>
|
|
template <typename U>
|
|
Curves<T>& operator *= (const Curves<U>& 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unary multiplication operator to multiply this object by a scalar of type T.
|
|
/// </summary>
|
|
/// <param name="t">The scalar to multiply this object by</param>
|
|
/// <returns>Reference to updated self</returns>
|
|
template <typename U>
|
|
Curves<T>& operator *= (const U& t)
|
|
{
|
|
for (auto& pp : m_Points)
|
|
for (auto& p : pp)
|
|
p *= T(t);
|
|
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the curve and weight values to their default state.
|
|
/// </summary>
|
|
void Init()
|
|
{
|
|
for (size_t i = 0; i < 4; i++)
|
|
Init(i);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set a specific curve and its weight value to their default state.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the curve and weight values to an empty state.
|
|
/// </summary>
|
|
void Clear()
|
|
{
|
|
for (auto& p : m_Points)
|
|
p.clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether any points are not the default.
|
|
/// </summary>
|
|
/// <returns>True if any point has been set to a value other than the default, else false.</returns>
|
|
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<std::vector<v2T>, 4> m_Points;
|
|
};
|
|
|
|
//Must declare this outside of the class to provide for both orders of parameters.
|
|
|
|
/// <summary>
|
|
/// Multiplication operator to multiply a Curves<T> object by a scalar of type U.
|
|
/// </summary>
|
|
/// <param name="curves">The curves object to multiply</param>
|
|
/// <param name="t">The scalar to multiply curves by by</param>
|
|
/// <returns>Copy of new Curves<T></returns>
|
|
template <typename T, typename U>
|
|
Curves<T> operator * (const Curves<T>& curves, const U& t)
|
|
{
|
|
T tt = T(t);
|
|
Curves<T> c(curves);
|
|
|
|
for (auto& pp : c.m_Points)
|
|
for (auto& p : pp)
|
|
p *= tt;
|
|
|
|
return c;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Multiplication operator for reverse order.
|
|
/// </summary>
|
|
/// <param name="t">The scalar to multiply curves by by</param>
|
|
/// <param name="curves">The curves object to multiply</param>
|
|
/// <returns>Copy of new Curves<T></returns>
|
|
template <typename T, typename U>
|
|
Curves<T> operator * (const U& t, const Curves<T>& curves)
|
|
{
|
|
return curves * t;
|
|
}
|
|
}
|