22.21.4.2 4/19/2021

--User changes
 -Allow users to set the Exp value when using the Exp temporal filter type.
 -Set the default temporal filter type to be Box, which does not alter the palette values at all during animation. This is done to avoid confusion when using Gaussian or Exp which can produce darkened images.

--Bug fixes
 -Sending a sequence to the final render dialog when the keyframes had non zero rotate and center Y values would produce off center animations when rendered.
 -Temporal filters were being unnecessarily recreated many times when rendering or generating sequences.
 -Exp filter was always treated like a Box filter.

--Code changes
 -Add a new member function SaveCurrentAsXml(QString filename = "") to the controllers which is only used for testing.
 -Modernize some C++ code.
This commit is contained in:
Person
2021-04-19 21:07:24 -06:00
parent 652ccc242c
commit 8086cfa731
97 changed files with 2156 additions and 2087 deletions

View File

@ -223,8 +223,8 @@ void Affine2D<T>::ScaleXY(T amount)
template <typename T>
void Affine2D<T>::Rotate(T rad)
{
m4T origMat4 = ToMat4ColMajor(true);//Must center and use column major for glm to work.
m4T newMat4 = glm::rotate(origMat4, rad, v3T(0, 0, 1));//Assuming only rotating around z.
const m4T origMat4 = ToMat4ColMajor(true);//Must center and use column major for glm to work.
const m4T newMat4 = glm::rotate(origMat4, rad, v3T(0, 0, 1));//Assuming only rotating around z.
A(newMat4[0][0]);//Use direct assignments instead of constructor to skip assigning C and F.
B(newMat4[0][1]);
D(newMat4[1][0]);
@ -234,8 +234,8 @@ void Affine2D<T>::Rotate(T rad)
template <typename T>
void Affine2D<T>::RotateTrans(T rad)
{
m4T origMat4 = TransToMat4ColMajor();//Only put translation in this matrix.
m4T newMat4 = glm::rotate(origMat4, rad, v3T(0, 0, 1));//Assuming only rotating around z.
const m4T origMat4 = TransToMat4ColMajor();//Only put translation in this matrix.
const m4T newMat4 = glm::rotate(origMat4, rad, v3T(0, 0, 1));//Assuming only rotating around z.
C(newMat4[0][3]);//Use direct assignments instead of constructor to skip assigning A, B, D, E.
F(newMat4[1][3]);
}
@ -257,7 +257,7 @@ void Affine2D<T>::Translate(const v2T& v)
template <typename T>
void Affine2D<T>::RotateScaleXTo(const v2T& v)
{
Affine2D<T> rs = CalcRotateScale(X(), v);
const Affine2D<T> rs = CalcRotateScale(X(), v);
X(rs.TransformNormal(X()));
Y(rs.TransformNormal(Y()));
}
@ -269,7 +269,7 @@ void Affine2D<T>::RotateScaleXTo(const v2T& v)
template <typename T>
void Affine2D<T>::RotateScaleYTo(const v2T& v)
{
Affine2D<T> rs = CalcRotateScale(Y(), v);
const Affine2D<T> rs = CalcRotateScale(Y(), v);
X(rs.TransformNormal(X()));
Y(rs.TransformNormal(Y()));
}
@ -281,7 +281,7 @@ void Affine2D<T>::RotateScaleYTo(const v2T& v)
template <typename T>
Affine2D<T> Affine2D<T>::Inverse() const
{
T det = A() * E() - D() * B();
const T det = A() * E() - D() * B();
return Affine2D<T>(E() / det, -D() / det,
-B() / det, A() / det,
(F() * B() - C() * E()) / det, (C() * D() - F() * A()) / det);
@ -341,10 +341,10 @@ typename m2T Affine2D<T>::ToMat2RowMajor() const
template <typename T>
typename m4T Affine2D<T>::ToMat4ColMajor(bool center) const
{
m4T mat(A(), B(), 0, center ? 0 : C(), //Col0...
D(), E(), 0, center ? 0 : F(), //1
0, 0, 1, 0, //2
0, 0, 0, 1);//3
const m4T mat(A(), B(), 0, center ? 0 : C(), //Col0...
D(), E(), 0, center ? 0 : F(), //1
0, 0, 1, 0, //2
0, 0, 0, 1);//3
return mat;
}
@ -356,20 +356,20 @@ typename m4T Affine2D<T>::ToMat4ColMajor(bool center) const
template <typename T>
typename m4T Affine2D<T>::ToMat4RowMajor(bool center) const
{
m4T mat(A(), D(), 0, 0,
B(), E(), 0, 0,
0, 0, 1, 0,
center ? 0 : C(), center ? 0 : F(), 0, 1);
const m4T mat(A(), D(), 0, 0,
B(), E(), 0, 0,
0, 0, 1, 0,
center ? 0 : C(), center ? 0 : F(), 0, 1);
return mat;
}
template <typename T>
typename m4T Affine2D<T>::TransToMat4ColMajor() const
{
m4T mat(1, 0, 0, C(), //Col0...
0, 1, 0, F(), //1
0, 0, 1, 0, //2
0, 0, 0, 1);//3
const m4T mat(1, 0, 0, C(), //Col0...
0, 1, 0, F(), //1
0, 0, 1, 0, //2
0, 0, 0, 1);//3
return mat;
}
@ -436,7 +436,7 @@ Affine2D<T> Affine2D<T>::CalcRotateScale(const v2T& from, const v2T& to)
template <typename T>
void Affine2D<T>::CalcRSAC(const v2T& from, const v2T& to, T& a, T& c)
{
T lsq = from.x * from.x + from.y * from.y;
const T lsq = from.x * from.x + from.y * from.y;
a = (from.y * to.y + from.x * to.x) / lsq;
c = (from.x * to.y - from.y * to.x) / lsq;
}

View File

@ -185,11 +185,11 @@ public:
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);
m_Points[i][0] = v2T{ 0 };
m_Points[i][1] = v2T{ static_cast<T>(0.25) };
m_Points[i][2] = v2T{ static_cast<T>(0.50) };
m_Points[i][3] = v2T{ static_cast<T>(0.75) };
m_Points[i][4] = v2T{ 1 };
}
}
@ -219,9 +219,9 @@ public:
}
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][1] != v2T(static_cast<T>(0.25))) ||
(m_Points[i][2] != v2T(static_cast<T>(0.50))) ||
(m_Points[i][3] != v2T(static_cast<T>(0.75))) ||
(m_Points[i][4] != v2T(1))
)
{

View File

@ -52,7 +52,7 @@ public:
//Make sure the values make sense.
if (m_Curve <= 0.0)
m_Curve = T(0.5);
m_Curve = static_cast<T>(0.5);
if (m_MaxRad < m_MinRad)
m_MaxRad = m_MinRad + 1;
@ -60,7 +60,7 @@ public:
//Ensure it's valid.
while (!Valid())
{
m_Curve += T(0.1);
m_Curve += static_cast<T>(0.1);
}
}
@ -121,7 +121,7 @@ public:
//
// num filters = (de_max_width / de_min_width)^(1 / estimator_curve)
//
decFilterCount = std::pow(finalMaxRad / finalMinRad, T(1.0) / m_Curve);
decFilterCount = std::pow(finalMaxRad / finalMinRad, static_cast<T>(1) / m_Curve);
if (decFilterCount > 1e7)//Too many filters.
return false;
@ -131,8 +131,8 @@ public:
//Condense the smaller kernels to save space.
if (intFilterCount > keepThresh)
{
maxIndex = static_cast<int>(ceil(DE_THRESH + std::pow(T(intFilterCount - DE_THRESH), m_Curve))) + 1;
m_MaxFilteredCounts = static_cast<int>(std::pow(T(maxIndex - DE_THRESH), T(1.0) / m_Curve)) + DE_THRESH;
maxIndex = static_cast<int>(ceil(DE_THRESH + std::pow(static_cast<T>(intFilterCount - DE_THRESH), m_Curve))) + 1;
m_MaxFilteredCounts = static_cast<int>(std::pow(static_cast<T>(maxIndex - DE_THRESH), static_cast<T>(1) / m_Curve)) + DE_THRESH;
}
else
{
@ -160,11 +160,11 @@ public:
//Calculate the filter width for this number of hits in a bin.
if (filterLoop < keepThresh)
{
filterHeight = (finalMaxRad / std::pow(T(filterLoop + 1), m_Curve));
filterHeight = (finalMaxRad / std::pow(static_cast<T>(filterLoop + 1), m_Curve));
}
else
{
loopAdjust = std::pow(T(filterLoop - keepThresh), (T(1.0) / m_Curve)) + keepThresh;
loopAdjust = std::pow(static_cast<T>(filterLoop - keepThresh), (static_cast<T>(1) / m_Curve)) + keepThresh;
filterHeight = (finalMaxRad / std::pow(loopAdjust + 1, m_Curve));
}
@ -182,7 +182,7 @@ public:
{
for (dek = -m_FilterWidth; dek <= m_FilterWidth; dek++)
{
filterVal = std::sqrt(T(dej * dej + dek * dek)) / filterHeight;
filterVal = std::sqrt(static_cast<T>(dej * dej + dek * dek)) / filterHeight;
//Only populate the coefs within this radius.
if (filterVal <= 1.0)
@ -197,7 +197,7 @@ public:
{
for (dek = 0; dek <= dej; dek++)
{
filterVal = std::sqrt(T(dej * dej + dek * dek)) / filterHeight;
filterVal = std::sqrt(static_cast<T>(dej * dej + dek * dek)) / filterHeight;
//Only populate the coefs within this radius.
if (filterVal > 1.0)
@ -258,7 +258,7 @@ public:
{
T finalMaxRad = m_MaxRad * m_Supersample + 1;
T finalMinRad = m_MinRad * m_Supersample + 1;
return std::pow(finalMaxRad / finalMinRad, T(1.0) / m_Curve) <= 1e7;
return std::pow(finalMaxRad / finalMinRad, static_cast<T>(1) / m_Curve) <= 1e7;
}
/// <summary>

View File

@ -596,7 +596,7 @@ public:
for (auto& xform : m_Xforms) norm += xform.m_Weight;
for (auto& weight : normalizedWeights) { weight = (norm == T(0) ? T(0) : m_Xforms[i].m_Weight / norm); i++; }
for (auto& weight : normalizedWeights) { weight = (norm == static_cast<T>( 0 ) ? static_cast<T>( 0 ) : m_Xforms[i].m_Weight / norm); i++; }
}
/// <summary>
@ -1082,8 +1082,8 @@ public:
/// <param name="rand">The random context to use for generating random symmetry</param>
void AddSymmetry(intmax_t sym, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{
intmax_t k;
size_t i, result = 0;
intmax_t k = 0;
size_t i = 0, result = 0;
T a;
if (sym == 0)
@ -1101,9 +1101,9 @@ public:
if (rand.RandBit())
sym = symDistrib[rand.Rand(Vlen(symDistrib))];
else if (rand.Rand() & 31)
sym = intmax_t(rand.Rand(13)) - 6;
sym = intmax_t{ rand.Rand(13) } - 6;
else
sym = intmax_t(rand.Rand(51)) - 25;
sym = intmax_t{ rand.Rand(51) } - 25;
}
if (sym == 1 || sym == 0)
@ -1132,7 +1132,7 @@ public:
sym = -sym;
}
a = T(2 * M_PI / sym);
a = static_cast<T>(2 * M_PI / sym);
for (k = 1; k < sym; k++)
{
@ -1142,7 +1142,7 @@ public:
m_Xforms[i].m_Weight = 1;
m_Xforms[i].m_ColorSpeed = 0;
m_Xforms[i].m_Animate = 0;
m_Xforms[i].m_ColorX = m_Xforms[i].m_ColorY = (sym < 3) ? 0 : (T(k - 1) / T(sym - 2));//Added Y.
m_Xforms[i].m_ColorX = m_Xforms[i].m_ColorY = (sym < 3) ? 0 : (static_cast<T>(k - 1) / static_cast<T>(sym - 2));//Added Y.
m_Xforms[i].m_Affine.A(Round6(std::cos(k * a)));
m_Xforms[i].m_Affine.D(Round6(std::sin(k * a)));
m_Xforms[i].m_Affine.B(Round6(-m_Xforms[i].m_Affine.D()));
@ -1452,7 +1452,7 @@ public:
m_AffineInterp = eAffineInterp::AFFINE_INTERP_LOG;
m_TemporalFilterType = eTemporalFilterType::BOX_TEMPORAL_FILTER;
m_TemporalFilterWidth = 1;
m_TemporalFilterExp = 0;
m_TemporalFilterExp = 1;
m_PaletteMode = ePaletteMode::PALETTE_LINEAR;
m_Interp = eInterp::EMBER_INTERP_SMOOTH;
}
@ -1559,8 +1559,8 @@ public:
<< "Spatial Filter Type: " << m_SpatialFilterType << "\n"
<< "Spatial Filter Radius: " << m_SpatialFilterRadius << "\n"
<< "Temporal Filter Type: " << m_TemporalFilterType << "\n"
<< "Temporal Filter Exp: " << m_TemporalFilterExp << "\n"
<< "Temporal Filter Width: " << m_TemporalFilterWidth << "\n"
<< "Temporal Filter Exp: " << m_TemporalFilterExp << "\n"
<< "Palette Mode: " << m_PaletteMode << "\n"
<< "Palette Interp: " << m_PaletteInterp << "\n"
<< "Palette Index: " << m_Palette.m_Index << "\n"
@ -1738,7 +1738,7 @@ public:
//Only used if temporal filter type is exp, else unused.
//Xml field: "temporal_filter_exp".
T m_TemporalFilterExp = 0;
T m_TemporalFilterExp = 1;
//The width of the temporal filter.
//Xml field: "temporal_filter_width".

View File

@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
namespace EmberNs
{
#define EMBER_VERSION "21.21.4.1"
#define EMBER_VERSION "22.21.4.2"
//#define FLAM3_COMPAT 1//Uncomment this if you want full compatibility with flam3 regarding some of the trig-based variations in Variations01.h
#define EPS6 T(1e-6)
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
@ -46,12 +46,12 @@ namespace EmberNs
#define DE_THRESH 100
#define DEG_2_RAD (M_PI / 180)
#define RAD_2_DEG (180 / M_PI)
#define DEG_2_RAD_T (T(M_PI) / T(180))
#define RAD_2_DEG_T (T(180) / T(M_PI))
#define M_2PI (T(M_PI * 2))
#define M_3PI (T(M_PI * 3))
#define M_PI2 (T(M_PI_2))
#define M_PI4 (T(M_PI_4))
#define DEG_2_RAD_T (T{M_PI} / T{180})
#define RAD_2_DEG_T (T{180} / T{M_PI})
#define M_2PI (T{M_PI * 2})
#define M_3PI (T{M_PI * 3})
#define M_PI2 (T{M_PI_2})
#define M_PI4 (T{M_PI_4})
#define M_SQRT3 T(1.7320508075688772935274463415059)
#define M_SQRT3_2 T(0.86602540378443864676372317075294)
#define M_SQRT3_3 T(0.57735026918962576450914878050196)

View File

@ -70,7 +70,7 @@ public:
MotionParam& operator = (const MotionParam<U>& other)
{
this->first = other.first;
this->second = T(other.second);
this->second = static_cast<T>(other.second);
return *this;
}
};

View File

@ -53,7 +53,7 @@ bool EmberToXml<T>::Save(const string& filename, C<Ember<T>, Alloc>& embers, siz
if (f.is_open())
{
auto prev = embers.begin();
const auto prev = embers.begin();
//Always ensure times make sense.
for (auto& ember : embers)
@ -280,7 +280,7 @@ string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, s
os << ">\n";
os << std::uppercase;
auto rows = ember.m_Palette.Size() / 8;
const auto rows = ember.m_Palette.Size() / 8;
for (i = 0; i < rows; i++)
{
@ -289,9 +289,9 @@ string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, s
for (j = 0; j < 8; j++)
{
size_t idx = 8 * i + j;
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][0] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][1] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][2] * 255));
os << hex << setw(2) << setfill('0') << static_cast<int>(std::rint(ember.m_Palette[idx][0] * 255));
os << hex << setw(2) << setfill('0') << static_cast<int>(std::rint(ember.m_Palette[idx][1] * 255));
os << hex << setw(2) << setfill('0') << static_cast<int>(std::rint(ember.m_Palette[idx][2] * 255));
}
os << "\n";
@ -304,10 +304,10 @@ string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, s
{
for (i = 0; i < ember.m_Palette.Size(); i++)
{
double r = ember.m_Palette[i][0] * 255;
double g = ember.m_Palette[i][1] * 255;
double b = ember.m_Palette[i][2] * 255;
double a = ember.m_Palette[i][3] * 255;
const double r = ember.m_Palette[i][0] * 255;
const double g = ember.m_Palette[i][1] * 255;
const double b = ember.m_Palette[i][2] * 255;
const double a = ember.m_Palette[i][3] * 255;
os << " ";
//The original used a precision of 6 which is totally unnecessary, use 2.
@ -463,7 +463,7 @@ xmlDocPtr EmberToXml<T>::CreateNewEditdoc(Ember<T>* parent0, Ember<T>* parent1,
{
os << "<comm>" << comment << "</comm>";
s = os.str();
commentDoc = xmlReadMemory(s.c_str(), int(s.length()), "comment.env", nullptr, XML_PARSE_NONET);
commentDoc = xmlReadMemory(s.c_str(), static_cast<int>(s.length()), "comment.env", nullptr, XML_PARSE_NONET);
os.str("");
//Check for errors.

View File

@ -1004,8 +1004,8 @@ public:
if (a.m_ColorSpeed < b.m_ColorSpeed) return false;
//Original did this every time, even though it's only needed if the color speeds are equal.
m2T aMat2 = a.m_Affine.ToMat2ColMajor();
m2T bMat2 = b.m_Affine.ToMat2ColMajor();
const auto aMat2 = a.m_Affine.ToMat2ColMajor();
const auto bMat2 = b.m_Affine.ToMat2ColMajor();
T ad = glm::determinant(aMat2);
T bd = glm::determinant(bMat2);

View File

@ -32,11 +32,11 @@
/// </summary>
#ifndef __ISAAC64
typedef uint ISAAC_INT;
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b9);
typedef uint ISAAC_INT;
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT{ 0x9e3779b9 };
#else
typedef size_t ISAAC_INT;
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b97f4a7c13);
typedef size_t ISAAC_INT;
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT{ 0x9e3779b97f4a7c13 };
#endif
namespace EmberNs
@ -251,7 +251,7 @@ public:
#ifdef ISAAC_FLAM3_DEBUG
return ((Rand() & 0xfffffff) - 0x7ffffff) / (floatType)0x7ffffff;
#else
return Frand<floatType>(floatType(-1), floatType(1));
return Frand<floatType>(floatType { -1 }, floatType { 1 });
#endif
}

View File

@ -278,12 +278,12 @@ public:
/// <param name="freq">Frequency 1 - 10</param>
void MakeAdjustedPalette(Palette<T>& palette, int rot, T hue, T sat, T bright, T cont, uint blur, uint freq)
{
T rgb[3], hsv[3];
T rgb[3] {}, hsv[3] {};
palette.m_Entries.resize(Size());
if (freq > 1)
{
size_t n = Size() / freq;
const size_t n = Size() / freq;
for (size_t j = 0; j <= freq; j++)
{

View File

@ -36,7 +36,7 @@ bool PaletteList<T>::AddPaletteFile(const string& filename, const vector<Palette
{
if (!GetPaletteListByFullPath(filename))
{
auto item = s_Palettes.insert(make_pair(filename, palettes));
const auto item = s_Palettes.insert(make_pair(filename, palettes));
Save(filename);
return true;
}
@ -55,7 +55,7 @@ bool PaletteList<T>::AddEmptyPaletteFile(const string& filename)
{
if (!GetPaletteListByFullPath(filename))
{
auto item = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
const auto item = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
Palette<T> p;
p.m_Index = 0;
p.m_Name = "empty-default";
@ -82,11 +82,11 @@ bool PaletteList<T>::AddEmptyPaletteFile(const string& filename)
template <typename T>
bool PaletteList<T>::AddPaletteToFile(const string& filename, const Palette<T>& palette)
{
if (auto p = GetPaletteListByFullPathOrFilename(filename))
if (const auto p = GetPaletteListByFullPathOrFilename(filename))
{
p->push_back(palette);
p->back().m_Filename = make_shared<string>(filename);//Ensure the filename matches because this could have been duplicated from another palette file.
p->back().m_Index = int(p->size()) - 1;
p->back().m_Index = static_cast<int>(p->size()) - 1;
Save(filename);
return true;
}
@ -105,13 +105,13 @@ bool PaletteList<T>::AddPaletteToFile(const string& filename, const Palette<T>&
template <typename T>
bool PaletteList<T>::Replace(const string& filename, const Palette<T>& palette)
{
if (auto p = GetPaletteListByFullPathOrFilename(filename))
if (const auto p = GetPaletteListByFullPathOrFilename(filename))
{
for (auto& pal : *p)
{
if (pal.m_Name == palette.m_Name)
{
auto index = pal.m_Index;
const auto index = pal.m_Index;
pal = palette;
pal.m_Index = index;
Save(filename);
@ -134,7 +134,7 @@ bool PaletteList<T>::Replace(const string& filename, const Palette<T>& palette)
template <typename T>
bool PaletteList<T>::Replace(const string& filename, const Palette<T>& palette, int index)
{
if (auto p = GetPaletteListByFullPathOrFilename(filename))
if (const auto p = GetPaletteListByFullPathOrFilename(filename))
{
if (index < p->size())
{
@ -160,7 +160,7 @@ bool PaletteList<T>::Delete(const string& filename, int index)
{
int i = 0;
if (auto p = GetPaletteListByFullPathOrFilename(filename))
if (const auto p = GetPaletteListByFullPathOrFilename(filename))
{
if (index < p->size())
{
@ -188,13 +188,13 @@ template <typename T>
bool PaletteList<T>::Add(const string& filename, bool force)
{
bool added = true;
bool contains = GetPaletteListByFullPathOrFilename(filename) != nullptr;
auto filenameonly = GetFilename(filename);
const auto contains = GetPaletteListByFullPathOrFilename(filename) != nullptr;
const auto filenameonly = GetFilename(filename);
if (contains && !force)//Don't allow any palettes with the same name, even if they reside in different paths.
return false;
auto palettes = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
const auto palettes = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
if (force || palettes.second)
{
@ -203,12 +203,12 @@ bool PaletteList<T>::Add(const string& filename, bool force)
if (ReadFile(filename.c_str(), buf))
{
auto lower = ToLower(filename);
auto pfilename = shared_ptr<string>(new string(filename));
const auto lower = ToLower(filename);
const auto pfilename = shared_ptr<string>(new string(filename));
if (EndsWith(lower, ".xml"))
{
xmlDocPtr doc = xmlReadMemory(static_cast<const char*>(buf.data()), int(buf.size()), filename.c_str(), nullptr, XML_PARSE_NONET);
const auto doc = xmlReadMemory(static_cast<const char*>(buf.data()), static_cast<int>(buf.size()), filename.c_str(), nullptr, XML_PARSE_NONET);
if (doc)
{
@ -270,7 +270,7 @@ Palette<T>* PaletteList<T>::GetRandomPalette()
while (attempts < Size() * 10)
{
auto p = s_Palettes.begin();
auto paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(Size());
const auto paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(Size());
size_t i = 0;
//Move p forward i elements.
@ -282,7 +282,7 @@ Palette<T>* PaletteList<T>::GetRandomPalette()
if (i < Size())
{
size_t paletteIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(p->second.size());
const size_t paletteIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(p->second.size());
if (paletteIndex < p->second.size() && !p->second[paletteIndex].IsEmpty())
return &p->second[paletteIndex];
@ -303,7 +303,7 @@ Palette<T>* PaletteList<T>::GetRandomPalette()
template <typename T>
Palette<T>* PaletteList<T>::GetPaletteByFilename(const string& filename, size_t i)
{
if (auto palettes = GetPaletteListByFilename(filename))
if (const auto palettes = GetPaletteListByFilename(filename))
if (i < palettes->size())
return &(*palettes)[i];
@ -319,7 +319,7 @@ Palette<T>* PaletteList<T>::GetPaletteByFilename(const string& filename, size_t
template <typename T>
Palette<T>* PaletteList<T>::GetPaletteByFullPath(const string& filename, size_t i)
{
if (auto palettes = GetPaletteListByFullPath(filename))
if (const auto palettes = GetPaletteListByFullPath(filename))
if (i < palettes->size())
return &(*palettes)[i];
@ -335,7 +335,7 @@ Palette<T>* PaletteList<T>::GetPaletteByFullPath(const string& filename, size_t
template <typename T>
Palette<T>* PaletteList<T>::GetPaletteByName(const string& filename, const string& name)
{
if (auto palettes = GetPaletteListByFullPathOrFilename(filename))
if (const auto palettes = GetPaletteListByFullPathOrFilename(filename))
for (auto& palette : *palettes)
if (palette.m_Name == name)
return &palette;
@ -351,7 +351,7 @@ Palette<T>* PaletteList<T>::GetPaletteByName(const string& filename, const strin
template <typename T>
vector<Palette<T>>* PaletteList<T>::GetPaletteListByFilename(const string& filename)
{
auto filenameonly = GetFilename(filename);
const auto filenameonly = GetFilename(filename);
for (auto& palettes : s_Palettes)
if (GetFilename(palettes.first) == filenameonly)
@ -368,7 +368,7 @@ vector<Palette<T>>* PaletteList<T>::GetPaletteListByFilename(const string& filen
template <typename T>
vector<Palette<T>>* PaletteList<T>::GetPaletteListByFullPath(const string& filename)
{
auto palettes = s_Palettes.find(filename);
const auto palettes = s_Palettes.find(filename);
if (palettes != s_Palettes.end() && !palettes->second.empty())
return &palettes->second;
@ -401,7 +401,7 @@ vector<Palette<T>>* PaletteList<T>::GetPaletteListByFullPathOrFilename(const str
template <typename T>
string PaletteList<T>::GetFullPathFromFilename(const string& filename)
{
auto filenameonly = GetFilename(filename);
const auto filenameonly = GetFilename(filename);
for (auto& palettes : s_Palettes)
if (GetFilename(palettes.first) == filenameonly)
@ -422,7 +422,7 @@ string PaletteList<T>::GetFullPathFromFilename(const string& filename)
template <typename T>
bool PaletteList<T>::GetHueAdjustedPalette(const string& filename, size_t i, T hue, Palette<T>& palette)
{
if (auto unadjustedPal = GetPaletteByFullPath(filename, i))
if (const auto unadjustedPal = GetPaletteByFullPath(filename, i))
{
unadjustedPal->MakeHueAdjustedPalette(palette, hue);
return true;
@ -508,7 +508,7 @@ const string& PaletteList<T>::Name(size_t index)
template <typename T>
bool PaletteList<T>::IsModifiable(const string& filename)
{
if (auto palFile = GetPaletteListByFullPathOrFilename(filename))
if (const auto palFile = GetPaletteListByFullPathOrFilename(filename))
for (auto& pal : *palFile)
if (pal.m_SourceColors.empty())
return false;
@ -534,14 +534,14 @@ const map<string, vector<Palette<T>>>& PaletteList<T>::Palettes() const
template <typename T>
bool PaletteList<T>::Save(const string& filename)
{
auto fullpath = GetFullPathFromFilename(filename);
const auto fullpath = GetFullPathFromFilename(filename);
try
{
size_t index = 0;
ostringstream os;
if (auto palFile = GetPaletteListByFullPathOrFilename(filename))
if (const auto palFile = GetPaletteListByFullPathOrFilename(filename))
{
ofstream f(fullpath);
os << "<palettes>\n";
@ -568,11 +568,11 @@ bool PaletteList<T>::Save(const string& filename)
{
for (int j = 0; j < 8; j++)
{
size_t idx = 8 * i + j;
const size_t idx = 8 * i + j;
os << "00";
os << hex << setw(2) << setfill('0') << int(std::rint(pal[idx][0] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(pal[idx][1] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(pal[idx][2] * 255));
os << hex << setw(2) << setfill('0') << static_cast<int>(std::rint(pal[idx][0] * 255));
os << hex << setw(2) << setfill('0') << static_cast<int>(std::rint(pal[idx][1] * 255));
os << hex << setw(2) << setfill('0') << static_cast<int>(std::rint(pal[idx][2] * 255));
}
os << "\n";
@ -651,7 +651,7 @@ void PaletteList<T>::ParsePalettes(xmlNode* node, const shared_ptr<string>& file
ss.clear();//Reset and fill the string stream.
ss.str(tmpStr);
ss >> tmp;//Do the conversion.
palette.m_Entries[colorCount][i] = T(tmp) / T(255);//Hex palette is [0..255], convert to [0..1].
palette.m_Entries[colorCount][i] = static_cast<T>(tmp) / static_cast<T>(255);//Hex palette is [0..255], convert to [0..1].
}
colorCount++;
@ -659,12 +659,12 @@ void PaletteList<T>::ParsePalettes(xmlNode* node, const shared_ptr<string>& file
}
else if (!Compare(attr->name, "source_colors"))
{
string s(val);
auto vec1 = Split(s, ' ');
const string s(val);
const auto vec1 = Split(s, ' ');
for (auto& v : vec1)
{
auto vec2 = Split(v, ',');
const auto vec2 = Split(v, ',');
if (vec2.size() == 4)
{

View File

@ -211,7 +211,7 @@ public:
r = 0;
g = 0;
b = 0;
a = norm ? T(1) : T(255);
a = norm ? T{ 1 } : T{ 255 };
}
};
}

View File

@ -11,7 +11,7 @@ Renderer<T, bucketT>::Renderer()
{
//Use a very large number regardless of the size of the output pixels. This should be sufficient granularity, even though
//it's technically less than the number of distinct values representable by a 32-bit float.
m_Csa.resize(size_t(CURVES_LENGTH));
m_Csa.resize(static_cast<size_t>(CURVES_LENGTH));
//Ensure the renderer at least has sane values for the camera upon startup.
//This is needed because due to timing/threading disconnects, the GUI can use the camera
//values before the render has started, which will lead to corrupt values.
@ -114,7 +114,7 @@ void Renderer<T, bucketT>::ComputeBounds()
template <typename T, typename bucketT>
void Renderer<T, bucketT>::ComputeQuality()
{
m_Scale = std::pow(T(2.0), Zoom());
m_Scale = std::pow(static_cast<T>(2), Zoom());
m_ScaledQuality = Quality() * SQR(m_Scale);
}
@ -130,11 +130,11 @@ void Renderer<T, bucketT>::ComputeCamera()
m_PixelsPerUnitY = m_PixelsPerUnitX;
m_PixelsPerUnitX /= PixelAspectRatio();
T shift = 0;
T t0 = T(m_GutterWidth) / (Supersample() * m_PixelsPerUnitX);
T t1 = T(m_GutterWidth) / (Supersample() * m_PixelsPerUnitY);
T t0 = static_cast<T>(m_GutterWidth) / (Supersample() * m_PixelsPerUnitX);
T t1 = static_cast<T>(m_GutterWidth) / (Supersample() * m_PixelsPerUnitY);
//These go from ll to ur, moving from negative to positive.
m_LowerLeftX = CenterX() - FinalRasW() / m_PixelsPerUnitX / T(2.0);
m_LowerLeftY = CenterY() - FinalRasH() / m_PixelsPerUnitY / T(2.0);
m_LowerLeftX = CenterX() - FinalRasW() / m_PixelsPerUnitX / static_cast<T>(2);
m_LowerLeftY = CenterY() - FinalRasH() / m_PixelsPerUnitY / static_cast<T>(2);
m_UpperRightX = m_LowerLeftX + FinalRasW() / m_PixelsPerUnitX;
m_UpperRightY = m_LowerLeftY + FinalRasH() / m_PixelsPerUnitY;
T carLlX = m_LowerLeftX - t0;
@ -258,7 +258,8 @@ bool Renderer<T, bucketT>::CreateDEFilter(bool& newAlloc)
(m_Ember.m_CurveDE != m_DensityFilter->Curve()) ||
(m_Ember.m_Supersample != m_DensityFilter->Supersample()))
{
m_DensityFilter = make_unique<DensityFilter<bucketT>>(bucketT(m_Ember.m_MinRadDE), bucketT(m_Ember.m_MaxRadDE), bucketT(m_Ember.m_CurveDE), m_Ember.m_Supersample);
m_DensityFilter = make_unique<DensityFilter<bucketT>>(static_cast<bucketT>(m_Ember.m_MinRadDE), static_cast<bucketT>(m_Ember.m_MaxRadDE),
static_cast<bucketT>(m_Ember.m_CurveDE), m_Ember.m_Supersample);
newAlloc = true;
}
@ -297,7 +298,8 @@ bool Renderer<T, bucketT>::CreateSpatialFilter(bool& newAlloc)
(m_PixelAspectRatio != m_SpatialFilter->PixelAspectRatio()))
{
m_SpatialFilter = unique_ptr<SpatialFilter<bucketT>>(
SpatialFilterCreator<bucketT>::Create(m_Ember.m_SpatialFilterType, bucketT(m_Ember.m_SpatialFilterRadius), m_Ember.m_Supersample, bucketT(m_PixelAspectRatio)));
SpatialFilterCreator<bucketT>::Create(m_Ember.m_SpatialFilterType,
static_cast<bucketT>(m_Ember.m_SpatialFilterRadius), m_Ember.m_Supersample, static_cast<bucketT>(m_PixelAspectRatio)));
m_Ember.m_SpatialFilterRadius = m_SpatialFilter->FilterRadius();//It may have been changed internally if it was too small, so ensure they're synced.
newAlloc = true;
}
@ -315,6 +317,7 @@ template <typename T, typename bucketT>
bool Renderer<T, bucketT>::CreateTemporalFilter(bool& newAlloc)
{
newAlloc = false;
//static int i = 0;
//Use intelligent testing so it isn't created every time a new ember is passed in.
if ((!m_TemporalFilter.get()) ||
@ -326,6 +329,14 @@ bool Renderer<T, bucketT>::CreateTemporalFilter(bool& newAlloc)
m_TemporalFilter = unique_ptr<TemporalFilter<T>>(
TemporalFilterCreator<T>::Create(m_Ember.m_TemporalFilterType, m_Ember.m_TemporalSamples, m_Ember.m_TemporalFilterWidth, m_Ember.m_TemporalFilterExp));
newAlloc = true;
//auto name = TemporalFilterCreator<T>::ToString(m_TemporalFilter->FilterType());
//ostringstream os;
//os << "./" << ++i << "_" << name << "_filter.txt";
//ofstream of (os.str());
//auto str = m_TemporalFilter->ToString();
//
//if (of.is_open())
// of << str;
}
return m_TemporalFilter.get() != nullptr;
@ -421,7 +432,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
}
//Make sure values are within valid range.
ClampGteRef(m_Ember.m_Supersample, size_t(1));
ClampGteRef(m_Ember.m_Supersample, static_cast<size_t>(1));
//Make sure to get most recent update since loop won't be entered to call Interp().
//Vib, gam and background are normally summed for each temporal sample. However if iteration is skipped, make sure to get the latest.
@ -442,7 +453,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
//it.Tic();
//Interpolate.
if (m_EmbersP->size() > 1)
m_Interpolater.Interpolate(*m_EmbersP, T(time), 0, m_Ember);
m_Interpolater.Interpolate(*m_EmbersP, static_cast<T>(time), 0, m_Ember);
//it.Toc("Interp 1");
@ -480,7 +491,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
}
}
deTime = T(time) + *m_TemporalFilter->Deltas();
deTime = static_cast<T>(time) + *m_TemporalFilter->Deltas();
//Interpolate and get an ember for DE purposes.
//Additional interpolation will be done in the temporal samples loop.
@ -506,7 +517,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
for (; (temporalSample < TemporalSamples()) && !m_Abort;)
{
T colorScalar = m_TemporalFilter->Filter()[temporalSample];
T temporalTime = T(time) + m_TemporalFilter->Deltas()[temporalSample];
T temporalTime = static_cast<T>(time) + m_TemporalFilter->Deltas()[temporalSample];
//Interpolate again.
//it.Tic();
@ -573,9 +584,9 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
{
m_Vibrancy += Vibrancy();
m_Gamma += Gamma();
m_Background.r += bucketT(m_Ember.m_Background.r);
m_Background.g += bucketT(m_Ember.m_Background.g);
m_Background.b += bucketT(m_Ember.m_Background.b);
m_Background.r += static_cast<bucketT>(m_Ember.m_Background.r);
m_Background.g += static_cast<bucketT>(m_Ember.m_Background.g);
m_Background.b += static_cast<bucketT>(m_Ember.m_Background.b);
m_VibGamCount++;
m_LastIter = 0;
temporalSample++;
@ -617,14 +628,14 @@ FilterAndAccum:
//to be very dark. Correct it by pretending the number of iters done is the exact quality desired and then scale according to that.
if (forceOutput)
{
T quality = (T(m_Stats.m_Iters) / T(FinalDimensions())) * (m_Scale * m_Scale);
m_K2 = bucketT((Supersample() * Supersample()) / (area * quality * m_TemporalFilter->SumFilt()));
T quality = (static_cast<T>(m_Stats.m_Iters) / static_cast<T>(FinalDimensions())) * (m_Scale * m_Scale);
m_K2 = static_cast<bucketT>((Supersample() * Supersample()) / (area * quality * m_TemporalFilter->SumFilt()));
}
else
m_K2 = bucketT((Supersample() * Supersample()) / (area * m_ScaledQuality * m_TemporalFilter->SumFilt()));
m_K2 = static_cast<bucketT>((Supersample() * Supersample()) / (area * m_ScaledQuality * m_TemporalFilter->SumFilt()));
}
else
m_K2 = bucketT(m_Ember.m_K2);
m_K2 = static_cast<bucketT>(m_Ember.m_K2);
if (!ResetBuckets(false, true))//Only the histogram was reset above, now reset the density filtering buffer.
{
@ -692,7 +703,7 @@ AccumOnly:
//Make sure a filter has been created.
CreateSpatialFilter(newFilterAlloc);
m_DensityFilterOffset = m_GutterWidth - size_t(Clamp<T>((T(m_SpatialFilter->FinalFilterWidth()) - T(Supersample())) / 2, 0, T(m_GutterWidth)));
m_DensityFilterOffset = m_GutterWidth - static_cast<size_t>(Clamp<T>((static_cast<T>(m_SpatialFilter->FinalFilterWidth()) - static_cast<T>(Supersample())) / 2, 0, static_cast<T>(m_GutterWidth)));
m_CurvesSet = m_Ember.m_Curves.CurvesSet();
ComputeCurves();//Color curves must be re-calculated as well.
@ -747,7 +758,7 @@ EmberImageComments Renderer<T, bucketT>::ImageComments(const EmberStats& stats,
EmberImageComments comments;
ss.imbue(std::locale(""));
comments.m_Genome = m_EmberToXml.ToString(m_Ember, "", printEditDepth, false, hexPalette);
ss << (double(stats.m_Badvals) / double(stats.m_Iters));//Percentage of bad values to iters.
ss << (static_cast<double>(stats.m_Badvals) / static_cast<double>(stats.m_Iters));//Percentage of bad values to iters.
comments.m_Badvals = ss.str(); ss.str("");
ss << stats.m_Iters;
comments.m_NumIters = ss.str(); ss.str("");//Total iters.
@ -767,7 +778,7 @@ EmberImageComments Renderer<T, bucketT>::ImageComments(const EmberStats& stats,
template <typename T, typename bucketT>
void Renderer<T, bucketT>::MakeDmap(T colorScalar)
{
m_Ember.m_Palette.template MakeDmap<bucketT>(m_Dmap, bucketT(colorScalar));
m_Ember.m_Palette.template MakeDmap<bucketT>(m_Dmap, static_cast<bucketT>(colorScalar));
}
/// <summary>
@ -778,8 +789,8 @@ void Renderer<T, bucketT>::MakeDmap(T colorScalar)
template <typename T, typename bucketT>
bool Renderer<T, bucketT>::Alloc(bool histOnly)
{
bool b = true;
bool lock =
auto b = true;
const auto lock =
(m_SuperSize != m_HistBuckets.size()) ||
(m_SuperSize != m_AccumulatorBuckets.size()) ||
(m_ThreadsToUse != m_Samples.size()) ||
@ -888,14 +899,14 @@ bool Renderer<T, bucketT>::ResetBuckets(bool resetHist, bool resetAccum)
template <typename T, typename bucketT>
void Renderer<T, bucketT>::VectorizedLogScale(size_t row, size_t rowEnd)
{
float k1 = float(m_K1);//All types must be float.
float k2 = float(m_K2);
const auto k1 = static_cast<float>(m_K1);//All types must be float.
const auto k2 = static_cast<float>(m_K2);
auto* __restrict hist = m_HistBuckets.data();//Vectorizer can't tell these point to different locations.
auto* __restrict acc = m_AccumulatorBuckets.data();
for (size_t i = row; i < rowEnd; i++)
{
float logScale = (k1 * std::log(1.0f + hist[i].a * k2)) / (hist[i].a + std::numeric_limits<float>::epsilon());
const float logScale = (k1 * std::log(1.0f + hist[i].a * k2)) / (hist[i].a + std::numeric_limits<float>::epsilon());
acc[i].r = hist[i].r * logScale;//Must break these out individually. Vectorizer can't reason about vec4's overloaded * operator.
acc[i].g = hist[i].g * logScale;
acc[i].b = hist[i].b * logScale;
@ -919,7 +930,7 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
//Timing t(4);
//Original didn't parallelize this, doing so gives a 50-75% speedup.
//The value can be directly assigned, which is quicker than summing.
parallel_for(startRow, endRow, size_t(1), [&](size_t j)
parallel_for(startRow, endRow, static_cast<size_t>(1), [&](size_t j)
{
size_t row = j * m_SuperRasW;
size_t rowEnd = row + endCol;
@ -931,7 +942,7 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
//Check for visibility first before doing anything else to avoid all possible unnecessary calculations.
if (m_HistBuckets[i].a != 0)
{
bucketT logScale = (m_K1 * std::log(1 + m_HistBuckets[i].a * m_K2)) / m_HistBuckets[i].a;
const bucketT logScale = (m_K1 * std::log(1 + m_HistBuckets[i].a * m_K2)) / m_HistBuckets[i].a;
//Original did a temporary assignment, then *= logScale, then passed the result to bump_no_overflow().
//Combine here into one operation for a slight speedup.
//Vectorized version:
@ -969,30 +980,30 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
{
Timing totalTime, localTime;
bool scf = !(Supersample() & 1);
intmax_t ss = Floor<T>(Supersample() / T(2));
T scfact = std::pow(Supersample() / (Supersample() + T(1)), T(2));
intmax_t ss = Floor<T>(Supersample() / static_cast<T>(2));
T scfact = std::pow(Supersample() / (Supersample() + static_cast<T>(1)), static_cast<T>(2));
size_t threads = m_ThreadsToUse;
size_t startRow = Supersample() - 1;
size_t endRow = m_SuperRasH - (Supersample() - 1);//Original did + which is most likely wrong.
intmax_t startCol = Supersample() - 1;
intmax_t endCol = m_SuperRasW - (Supersample() - 1);
size_t chunkSize = size_t(ceil(double(endRow - startRow) / double(threads)));
size_t chunkSize = static_cast<size_t>(std::ceil(static_cast<double>(endRow - startRow) / static_cast<double>(threads)));
//parallel_for scales very well, dividing the work almost perfectly among all processors.
parallel_for(size_t(0), threads, size_t(1), [&] (size_t threadIndex)
parallel_for(static_cast<size_t>(0), threads, static_cast<size_t>(1), [&] (size_t threadIndex)
{
size_t pixelNumber = 0;
int localStartRow = int(std::min<size_t>(startRow + (threadIndex * chunkSize), endRow - 1));
int localEndRow = int(std::min<size_t>(localStartRow + chunkSize, endRow));
size_t pixelsThisThread = size_t(localEndRow - localStartRow) * m_SuperRasW;
const auto localStartRow = static_cast<intmax_t>(std::min<size_t>(startRow + (threadIndex * chunkSize), endRow - 1));
const auto localEndRow = static_cast<intmax_t>(std::min<size_t>(localStartRow + chunkSize, endRow));
const size_t pixelsThisThread = static_cast<size_t>(localEndRow - localStartRow) * m_SuperRasW;
double lastPercent = 0;
tvec4<bucketT, glm::defaultp> logScaleBucket;
for (intmax_t j = localStartRow; (j < localEndRow) && !m_Abort; j++)
{
auto buckets = m_HistBuckets.data();
auto bucketRowStart = buckets + (j * m_SuperRasW);//Pull out of inner loop for optimization.
auto filterCoefs = m_DensityFilter->Coefs();
auto filterWidths = m_DensityFilter->Widths();
const auto buckets = m_HistBuckets.data();
const auto bucketRowStart = buckets + (j * m_SuperRasW);//Pull out of inner loop for optimization.
const auto filterCoefs = m_DensityFilter->Coefs();
const auto filterWidths = m_DensityFilter->Widths();
for (intmax_t i = startCol; i < endCol; i++)
{
@ -1005,7 +1016,7 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
if (bucket->a == 0)
continue;
bucketT cacheLog = (m_K1 * std::log(1 + bucket->a * m_K2)) / bucket->a;//Caching this calculation gives a 30% speedup.
const bucketT cacheLog = (m_K1 * std::log(1 + bucket->a * m_K2)) / bucket->a;//Caching this calculation gives a 30% speedup.
if (ss == 0)
{
@ -1016,10 +1027,10 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
//The original contained a glaring flaw as it would run past the boundaries of the buffers
//when calculating the density for a box centered on the last row or column.
//Clamp here to not run over the edge.
intmax_t densityBoxLeftX = (i - std::min(i, ss));
intmax_t densityBoxRightX = (i + std::min(ss, intmax_t(m_SuperRasW) - i - 1));
intmax_t densityBoxTopY = (j - std::min(j, ss));
intmax_t densityBoxBottomY = (j + std::min(ss, intmax_t(m_SuperRasH) - j - 1));
const intmax_t densityBoxLeftX = (i - std::min(i, ss));
const intmax_t densityBoxRightX = (i + std::min(ss, static_cast<intmax_t>(m_SuperRasW) - i - 1));
const intmax_t densityBoxTopY = (j - std::min(j, ss));
const intmax_t densityBoxBottomY = (j + std::min(ss, static_cast<intmax_t>(m_SuperRasH) - j - 1));
//Count density in ssxss area.
//Original went one col at a time, which is cache inefficient. Go one row at at time here for a slight speedup.
@ -1035,9 +1046,9 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
if (filterSelect > m_DensityFilter->MaxFilteredCounts())
filterSelectInt = m_DensityFilter->MaxFilterIndex();
else if (filterSelect <= DE_THRESH)
filterSelectInt = size_t(ceil(filterSelect)) - 1;
filterSelectInt = static_cast<size_t>(std::ceil(filterSelect)) - 1;
else
filterSelectInt = DE_THRESH + size_t(Floor<T>(std::pow(filterSelect - DE_THRESH, m_DensityFilter->Curve())));
filterSelectInt = DE_THRESH + static_cast<size_t>(Floor<T>(std::pow(filterSelect - DE_THRESH, m_DensityFilter->Curve())));
//If the filter selected below the min specified clamp it to the min.
if (filterSelectInt > m_DensityFilter->MaxFilterIndex())
@ -1045,7 +1056,7 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
//Only have to calculate the values for ~1/8 of the square.
filterCoefIndex = filterSelectInt * m_DensityFilter->KernelSize();
arrFilterWidth = intmax_t(ceil(filterWidths[filterSelectInt])) - 1;
arrFilterWidth = static_cast<intmax_t>(std::ceil(filterWidths[filterSelectInt])) - 1;
for (jj = 0; jj <= arrFilterWidth; jj++)
{
@ -1096,13 +1107,13 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
if (m_Callback && threadIndex == 0)
{
pixelNumber += m_SuperRasW;
double percent = (double(pixelNumber) / double(pixelsThisThread)) * 100.0;
double percentDiff = percent - lastPercent;
double toc = localTime.Toc();
const auto percent = (static_cast<double>(pixelNumber) / static_cast<double>(pixelsThisThread)) * 100.0;
const auto percentDiff = percent - lastPercent;
const auto toc = localTime.Toc();
if (percentDiff >= 10 || (toc > 1000 && percentDiff >= 1))
{
double etaMs = ((100.0 - percent) / percent) * totalTime.Toc();
const auto etaMs = ((100.0 - percent) / percent) * totalTime.Toc();
if (!m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, percent, 1, etaMs))
Abort();
@ -1144,7 +1155,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels,
}
//Timing t(4);
size_t filterWidth = m_SpatialFilter->FinalFilterWidth();
const size_t filterWidth = m_SpatialFilter->FinalFilterWidth();
bucketT g, linRange, vibrancy;
Color<bucketT> background;
auto p = pixels.data();
@ -1155,10 +1166,10 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels,
//The original does it this way as well and it's roughly 11 times faster to do it this way than inline below with each pixel.
if (EarlyClip())
{
parallel_for(size_t(0), m_SuperRasH, size_t(1), [&](size_t j)
parallel_for(static_cast<size_t>(0), m_SuperRasH, static_cast<size_t>(1), [&](size_t j)
{
auto rowStart = m_AccumulatorBuckets.data() + (j * m_SuperRasW);//Pull out of inner loop for optimization.
auto rowEnd = rowStart + m_SuperRasW;
const auto rowEnd = rowStart + m_SuperRasW;
while (rowStart < rowEnd && !m_Abort)//Use the pointer itself as the offset to save an extra addition per iter.
{
@ -1182,7 +1193,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels,
//otherwise artifacts that resemble page tearing will occur in an interactive run. It's
//critical to never exit this loop prematurely.
//for (size_t j = 0; j < FinalRasH(); j++)//Keep around for debugging.
parallel_for(size_t(0), FinalRasH(), size_t(1), [&](size_t j)
parallel_for(static_cast<size_t>(0), FinalRasH(), static_cast<size_t>(1), [&](size_t j)
{
Color<bucketT> newBucket;
size_t pixelsRowStart = (m_YAxisUp ? ((FinalRasH() - j) - 1) : j) * FinalRasW();//Pull out of inner loop for optimization.
@ -1193,8 +1204,8 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels,
for (size_t i = 0; i < FinalRasW(); i++, pv4T++)
{
size_t ii, jj;
size_t x = m_DensityFilterOffset + (i * Supersample());//Start at the beginning column of each super sample block.
size_t clampedFilterW = std::min(filterWidth, m_SuperRasW - x);//Make sure the filter doesn't go past the right of the gutter.
const size_t x = m_DensityFilterOffset + (i * Supersample());//Start at the beginning column of each super sample block.
const size_t clampedFilterW = std::min(filterWidth, m_SuperRasW - x);//Make sure the filter doesn't go past the right of the gutter.
newBucket.Clear();
//Original was iterating column-wise, which is slow.
@ -1233,7 +1244,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels,
{
for (i = 0; i < FinalRasW(); i++)
{
auto pp = p + (i + j * FinalRasW());
const auto pp = p + (i + j * FinalRasW());
pp->r = m_TempEmber.m_Palette[i * 256 / FinalRasW()][0];
pp->g = m_TempEmber.m_Palette[i * 256 / FinalRasW()][1];
pp->b = m_TempEmber.m_Palette[i * 256 / FinalRasW()][2];
@ -1266,7 +1277,7 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
{
//Timing t2(4);
m_IterTimer.Tic();
size_t totalItersPerThread = size_t(ceil(double(iterCount) / double(m_ThreadsToUse)));
const size_t totalItersPerThread = static_cast<size_t>(std::ceil(static_cast<double>(iterCount) / static_cast<double>(m_ThreadsToUse)));
EmberStats stats;
//vector<double> accumTimes(4);
@ -1277,16 +1288,16 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
m_ThreadEmbers.insert(m_ThreadEmbers.begin(), m_ThreadsToUse, m_Ember);
}
parallel_for(size_t(0), m_ThreadsToUse, size_t(1), [&] (size_t threadIndex)
parallel_for(static_cast<size_t>(0), m_ThreadsToUse, static_cast<size_t>(1), [&] (size_t threadIndex)
{
#if defined(_WIN32)
SetThreadPriority(GetCurrentThread(), int(m_Priority));
SetThreadPriority(GetCurrentThread(), static_cast<int>(m_Priority));
#elif defined(__APPLE__)
sched_param sp = {0};
sp.sched_priority = int(m_Priority);
sp.sched_priority = static_cast<int>(m_Priority);
pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
#else
pthread_setschedprio(pthread_self(), int(m_Priority));
pthread_setschedprio(pthread_self(), static_cast<int>(m_Priority));
#endif
//Timing t;
IterParams<T> params;
@ -1334,27 +1345,27 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
if (m_Callback && threadIndex == 0)
{
auto percent = 100.0 *
double
static_cast<double>
(
double
static_cast<double>
(
double
static_cast<double>
(
//Takes progress of current thread and multiplies by thread count.
//This assumes the threads progress at roughly the same speed.
//Adding m_LastIter is done so that an incremental render still gives an accurate percentage.
double(m_LastIter + (m_SubBatch[threadIndex] * m_ThreadsToUse)) / double(ItersPerTemporalSample())
static_cast<double>(m_LastIter + (m_SubBatch[threadIndex] * m_ThreadsToUse)) / static_cast<double>(ItersPerTemporalSample())
) + temporalSample
) / double(TemporalSamples())
) / static_cast<double>(TemporalSamples())
);
double percentDiff = percent - m_LastIterPercent;
double toc = m_ProgressTimer.Toc();
const auto percentDiff = percent - m_LastIterPercent;
const auto toc = m_ProgressTimer.Toc();
if (percentDiff >= 10 || (toc > 1000 && percentDiff >= 1))//Call callback function if either 10% has passed, or one second (and 1%).
{
auto startingpercent = 100.0 * (m_LastIter / double(ItersPerTemporalSample()));//This is done to support incremental renders, starting from the percentage it left off on.
auto currentpercent = percent - startingpercent;//Current percent in terms of starting percentage. So starting at 50% and progressing 5% will give a value of 5%, not 55%.
auto etaMs = currentpercent == 0 ? 0 : (((100.0 - startingpercent) - currentpercent) / currentpercent) * m_RenderTimer.Toc();//Subtract startingpercent from 100% so that it's properly scaled, meaning rendering from 50% - 100% will be treated as 0% - 100%.
const auto startingpercent = 100.0 * (m_LastIter / static_cast<double>(ItersPerTemporalSample()));//This is done to support incremental renders, starting from the percentage it left off on.
const auto currentpercent = percent - startingpercent;//Current percent in terms of starting percentage. So starting at 50% and progressing 5% will give a value of 5%, not 55%.
const auto etaMs = currentpercent == 0 ? 0 : (((100.0 - startingpercent) - currentpercent) / currentpercent) * m_RenderTimer.Toc();//Subtract startingpercent from 100% so that it's properly scaled, meaning rendering from 50% - 100% will be treated as 0% - 100%.
if (!m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, percent, 0, etaMs))
Abort();
@ -1418,11 +1429,11 @@ template <typename T, typename bucketT> TemporalFilter<T>* Renderer<T, buck
/// Virtual renderer properties overridden from RendererBase, getters only.
/// </summary>
template <typename T, typename bucketT> double Renderer<T, bucketT>::ScaledQuality() const { return double(m_ScaledQuality); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::LowerLeftX(bool gutter) const { return double(gutter ? m_CarToRas.CarLlX() : m_LowerLeftX); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::LowerLeftY(bool gutter) const { return double(gutter ? m_CarToRas.CarLlY() : m_LowerLeftY); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::UpperRightX(bool gutter) const { return double(gutter ? m_CarToRas.CarUrX() : m_UpperRightX); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::UpperRightY(bool gutter) const { return double(gutter ? m_CarToRas.CarUrY() : m_UpperRightY); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::ScaledQuality() const { return static_cast<double>(m_ScaledQuality); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::LowerLeftX(bool gutter) const { return static_cast<double>(gutter ? m_CarToRas.CarLlX() : m_LowerLeftX); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::LowerLeftY(bool gutter) const { return static_cast<double>(gutter ? m_CarToRas.CarLlY() : m_LowerLeftY); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::UpperRightX(bool gutter) const { return static_cast<double>(gutter ? m_CarToRas.CarUrX() : m_UpperRightX); }
template <typename T, typename bucketT> double Renderer<T, bucketT>::UpperRightY(bool gutter) const { return static_cast<double>(gutter ? m_CarToRas.CarUrY() : m_UpperRightY); }
template <typename T, typename bucketT> DensityFilterBase* Renderer<T, bucketT>::GetDensityFilter() { return m_DensityFilter.get(); }
/// <summary>
@ -1440,11 +1451,11 @@ template <typename T, typename bucketT> T Renderer<T, bucket
template <typename T, typename bucketT> T Renderer<T, bucketT>::CenterX() const { return m_Ember.m_CenterX; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::CenterY() const { return m_Ember.m_CenterY; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Rotate() const { return m_Ember.m_Rotate; }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Brightness() const { return bucketT(m_Ember.m_Brightness); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Gamma() const { return bucketT(m_Ember.m_Gamma); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Vibrancy() const { return bucketT(m_Ember.m_Vibrancy); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::GammaThresh() const { return bucketT(m_Ember.m_GammaThresh); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::HighlightPower() const { return bucketT(m_Ember.m_HighlightPower); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Brightness() const { return static_cast<bucketT>(m_Ember.m_Brightness); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Gamma() const { return static_cast<bucketT>(m_Ember.m_Gamma); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Vibrancy() const { return static_cast<bucketT>(m_Ember.m_Vibrancy); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::GammaThresh() const { return static_cast<bucketT>(m_Ember.m_GammaThresh); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::HighlightPower() const { return static_cast<bucketT>(m_Ember.m_HighlightPower); }
template <typename T, typename bucketT> Color<T> Renderer<T, bucketT>::Background() const { return m_Ember.m_Background; }
template <typename T, typename bucketT> const Xform<T>* Renderer<T, bucketT>::Xforms() const { return m_Ember.Xforms(); }
template <typename T, typename bucketT> Xform<T>* Renderer<T, bucketT>::NonConstXforms() { return m_Ember.NonConstXforms(); }
@ -1491,13 +1502,13 @@ void Renderer<T, bucketT>::PrepFinalAccumVals(Color<bucketT>& background, bucket
//sample, which means the values will be zero.
vibrancy = m_Vibrancy == 0 ? Vibrancy() : m_Vibrancy;
size_t vibGamCount = m_VibGamCount == 0 ? 1 : m_VibGamCount;
bucketT gamma = m_Gamma == 0 ? Gamma() : m_Gamma;
g = 1 / ClampGte<bucketT>(gamma / vibGamCount, bucketT(0.01));//Ensure a divide by zero doesn't occur.
const bucketT gamma = m_Gamma == 0 ? Gamma() : m_Gamma;
g = 1 / ClampGte<bucketT>(gamma / vibGamCount, static_cast<bucketT>(0.01));//Ensure a divide by zero doesn't occur.
linRange = GammaThresh();
vibrancy /= vibGamCount;
background.x = (IsNearZero(m_Background.r) ? bucketT(m_Ember.m_Background.r) : m_Background.r) / vibGamCount;
background.y = (IsNearZero(m_Background.g) ? bucketT(m_Ember.m_Background.g) : m_Background.g) / vibGamCount;
background.z = (IsNearZero(m_Background.b) ? bucketT(m_Ember.m_Background.b) : m_Background.b) / vibGamCount;
background.x = (IsNearZero(m_Background.r) ? static_cast<bucketT>(m_Ember.m_Background.r) : m_Background.r) / vibGamCount;
background.y = (IsNearZero(m_Background.g) ? static_cast<bucketT>(m_Ember.m_Background.g) : m_Background.g) / vibGamCount;
background.z = (IsNearZero(m_Background.b) ? static_cast<bucketT>(m_Ember.m_Background.b) : m_Background.b) / vibGamCount;
}
/// <summary>
@ -1516,7 +1527,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
{
size_t histIndex, intColorIndex, histSize = m_HistBuckets.size();
bucketT colorIndex, colorIndexFrac;
auto psm1 = m_Ember.m_Palette.Size() - 1;
const auto psm1 = m_Ember.m_Palette.Size() - 1;
//Linear is a linear scale for when the color index is not a whole number, which is most of the time.
//It uses a portion of the value of the index, and the remainder of the next index.
@ -1526,7 +1537,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
//Use overloaded addition and multiplication operators in vec4 to perform the accumulation.
if (PaletteMode() == ePaletteMode::PALETTE_LINEAR)
{
auto psm2 = psm1 - 1;
const auto psm2 = psm1 - 1;
//It's critical to understand what's going on here as it's one of the most important parts of the algorithm.
//A color value gets retrieved from the palette and
@ -1564,8 +1575,8 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
//This will result in a few points at the very edges getting discarded, but prevents a crash and doesn't seem to make a speed difference.
if (histIndex < histSize)
{
colorIndex = bucketT(p.m_ColorX) * psm1;
intColorIndex = size_t(colorIndex);
colorIndex = static_cast<bucketT>(p.m_ColorX) * psm1;
intColorIndex = static_cast<size_t>(colorIndex);
if (intColorIndex < 0)
{
@ -1579,13 +1590,13 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
}
else
{
colorIndexFrac = colorIndex - bucketT(intColorIndex);//Interpolate between intColorIndex and intColorIndex + 1.
colorIndexFrac = colorIndex - static_cast<bucketT>(intColorIndex);//Interpolate between intColorIndex and intColorIndex + 1.
}
bucketT* __restrict hist = glm::value_ptr(m_HistBuckets[histIndex]);//Vectorizer can't tell these point to different locations.
const bucketT* __restrict pal = glm::value_ptr(palette->m_Entries[intColorIndex]);
const bucketT* __restrict pal2 = glm::value_ptr(palette->m_Entries[intColorIndex + 1]);
auto cifm1 = bucketT(1) - colorIndexFrac;
const auto cifm1 = static_cast<bucketT>(1) - colorIndexFrac;
//Loops are unrolled to allow auto vectorization.
if (p.m_Opacity == 1)
@ -1597,7 +1608,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
}
else
{
auto va = bucketT(p.m_Opacity);
const auto va = static_cast<bucketT>(p.m_Opacity);
hist[0] += ((pal[0] * cifm1) + (pal2[0] * colorIndexFrac)) * va;
hist[1] += ((pal[1] * cifm1) + (pal2[1] * colorIndexFrac)) * va;
hist[2] += ((pal[2] * cifm1) + (pal2[2] * colorIndexFrac)) * va;
@ -1618,8 +1629,8 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
{
if (Rotate() != 0)
{
T p00 = p.m_X - m_Ember.m_CenterX;
T p11 = p.m_Y - m_Ember.m_RotCenterY;
const T p00 = p.m_X - m_Ember.m_CenterX;
const T p11 = p.m_Y - m_Ember.m_RotCenterY;
p.m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + m_Ember.m_CenterX;
p.m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY;
}
@ -1630,7 +1641,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
if (histIndex < histSize)
{
intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * psm1), 0, psm1);
intColorIndex = Clamp<size_t>(static_cast<size_t>(p.m_ColorX * psm1), 0, psm1);
bucketT* __restrict hist = glm::value_ptr(m_HistBuckets[histIndex]);//Vectorizer can't tell these point to different locations.
const bucketT* __restrict pal = glm::value_ptr(palette->m_Entries[intColorIndex]);
@ -1643,7 +1654,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
}
else
{
auto va = bucketT(p.m_Opacity);
auto va = static_cast<bucketT>(p.m_Opacity);
hist[0] += pal[0] * va;
hist[1] += pal[1] * va;
hist[2] += pal[2] * va;
@ -1667,7 +1678,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
template <typename T, typename bucketT>
void Renderer<T, bucketT>::AddToAccum(const tvec4<bucketT, glm::defaultp>& bucket, intmax_t i, intmax_t ii, intmax_t j, intmax_t jj)
{
if (j + jj >= 0 && j + jj < intmax_t(m_SuperRasH) && i + ii >= 0 && i + ii < intmax_t(m_SuperRasW))
if (j + jj >= 0 && j + jj < static_cast<intmax_t>(m_SuperRasH) && i + ii >= 0 && i + ii < static_cast<intmax_t>(m_SuperRasW))
{
auto* __restrict accum = m_AccumulatorBuckets.data() + ((i + ii) + ((j + jj) * m_SuperRasW));//For vectorizer, results in a 33% speedup.
accum->r += bucket.r;
@ -1695,7 +1706,7 @@ template <typename T, typename bucketT>
template <typename accumT>
void Renderer<T, bucketT>::GammaCorrection(tvec4<bucketT, glm::defaultp>& bucket, Color<bucketT>& background, bucketT g, bucketT linRange, bucketT vibrancy, bool scale, accumT* correctedChannels)
{
auto bt1 = bucketT(1);
auto bt1 = static_cast<bucketT>(1);
if (scale && EarlyClip())
{
@ -1706,10 +1717,10 @@ void Renderer<T, bucketT>::GammaCorrection(tvec4<bucketT, glm::defaultp>& bucket
CurveAdjust(bucket.b, 3);
}
correctedChannels[0] = accumT(Clamp<bucketT>(bucket.r, 0, bt1));
correctedChannels[1] = accumT(Clamp<bucketT>(bucket.g, 0, bt1));
correctedChannels[2] = accumT(Clamp<bucketT>(bucket.b, 0, bt1));
correctedChannels[3] = accumT(Clamp<bucketT>(bucket.a, 0, bt1));
correctedChannels[0] = static_cast<accumT>(Clamp<bucketT>(bucket.r, 0, bt1));
correctedChannels[1] = static_cast<accumT>(Clamp<bucketT>(bucket.g, 0, bt1));
correctedChannels[2] = static_cast<accumT>(Clamp<bucketT>(bucket.b, 0, bt1));
correctedChannels[3] = static_cast<accumT>(Clamp<bucketT>(bucket.a, 0, bt1));
}
else
{
@ -1737,10 +1748,10 @@ void Renderer<T, bucketT>::GammaCorrection(tvec4<bucketT, glm::defaultp>& bucket
if (scale && m_CurvesSet)
CurveAdjust(a, rgbi + 1);
correctedChannels[rgbi] = accumT(Clamp<bucketT>(a, 0, bt1));//Early clip, just assign directly.
correctedChannels[rgbi] = static_cast<accumT>(Clamp<bucketT>(a, 0, bt1));//Early clip, just assign directly.
}
correctedChannels[3] = accumT(alpha);
correctedChannels[3] = static_cast<accumT>(alpha);
}
}
@ -1775,8 +1786,8 @@ void Renderer<T, bucketT>::ComputeCurves()
template <typename T, typename bucketT>
void Renderer<T, bucketT>::CurveAdjust(bucketT& a, const glm::length_t& index)
{
size_t tempIndex = size_t(Clamp<bucketT>(a * CURVES_LENGTH_M1, 0, CURVES_LENGTH_M1));
size_t tempIndex2 = size_t(Clamp<bucketT>(m_Csa[tempIndex].x * CURVES_LENGTH_M1, 0, CURVES_LENGTH_M1));
size_t tempIndex = static_cast<size_t>(Clamp<bucketT>(a * CURVES_LENGTH_M1, 0, CURVES_LENGTH_M1));
size_t tempIndex2 = static_cast<size_t>(Clamp<bucketT>(m_Csa[tempIndex].x * CURVES_LENGTH_M1, 0, CURVES_LENGTH_M1));
a = m_Csa[tempIndex2][index];
}

View File

@ -55,21 +55,21 @@ public:
bool AssignIterator();
//Virtual processing functions overriden from RendererBase.
virtual void Prepare() override;
virtual void ComputeBounds() override;
virtual void ComputeQuality() override;
virtual void ComputeCamera() override;
virtual void SetEmber(const Ember<T>& ember, eProcessAction action = eProcessAction::FULL_RENDER, bool prep = false) override;
void Prepare() override;
void ComputeBounds() override;
void ComputeQuality() override;
void ComputeCamera() override;
void SetEmber(const Ember<T>& ember, eProcessAction action = eProcessAction::FULL_RENDER, bool prep = false) override;
template <typename C>
void SetEmber(const C& embers);
void MoveEmbers(vector<Ember<T>>& embers);
void SetExternalEmbersPointer(vector<Ember<T>>* embers);
virtual bool CreateDEFilter(bool& newAlloc) override;
virtual bool CreateSpatialFilter(bool& newAlloc) override;
virtual bool CreateTemporalFilter(bool& newAlloc) override;
virtual size_t HistBucketSize() const override { return sizeof(tvec4<bucketT, glm::defaultp>); }
virtual eRenderStatus Run(vector<v4F>& finalImage, double time = 0, size_t subBatchCountOverride = 0, bool forceOutput = false, size_t finalOffset = 0) override;
virtual EmberImageComments ImageComments(const EmberStats& stats, size_t printEditDepth = 0, bool hexPalette = true) override;
bool CreateDEFilter(bool& newAlloc) override;
bool CreateSpatialFilter(bool& newAlloc) override;
bool CreateTemporalFilter(bool& newAlloc) override;
size_t HistBucketSize() const override { return sizeof(tvec4<bucketT, glm::defaultp>); }
eRenderStatus Run(vector<v4F>& finalImage, double time = 0, size_t subBatchCountOverride = 0, bool forceOutput = false, size_t finalOffset = 0) override;
EmberImageComments ImageComments(const EmberStats& stats, size_t printEditDepth = 0, bool hexPalette = true) override;
protected:
//New virtual functions to be overridden in derived renderers that use the GPU, but not accessed outside.
@ -100,12 +100,12 @@ public:
inline TemporalFilter<T>* GetTemporalFilter();
//Virtual renderer properties overridden from RendererBase, getters only.
virtual double ScaledQuality() const override;
virtual double LowerLeftX(bool gutter = true) const override;
virtual double LowerLeftY(bool gutter = true) const override;
virtual double UpperRightX(bool gutter = true) const override;
virtual double UpperRightY(bool gutter = true) const override;
virtual DensityFilterBase* GetDensityFilter() override;
double ScaledQuality() const override;
double LowerLeftX(bool gutter = true) const override;
double LowerLeftY(bool gutter = true) const override;
double UpperRightX(bool gutter = true) const override;
double UpperRightY(bool gutter = true) const override;
DensityFilterBase* GetDensityFilter() override;
//Non-virtual ember wrappers, getters only.
inline bool XaosPresent() const;
@ -135,11 +135,11 @@ public:
inline ePaletteMode PaletteMode() const;
//Virtual ember wrappers overridden from RendererBase, getters only.
virtual size_t TemporalSamples() const override;
virtual size_t FinalRasW() const override;
virtual size_t FinalRasH() const override;
virtual size_t SubBatchSize() const override;
virtual size_t FuseCount() const override;
size_t TemporalSamples() const override;
size_t FinalRasW() const override;
size_t FinalRasH() const override;
size_t SubBatchSize() const override;
size_t FuseCount() const override;
//Non-virtual iterator wrappers.
const byte* XformDistributions() const;

View File

@ -174,7 +174,7 @@ bool RendererBase::RandVec(vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>>& randVec)
bool RendererBase::PrepFinalAccumVector(vector<v4F>& pixels)
{
EnterResize();
size_t size = FinalDimensions();
const auto size = FinalDimensions();
if (m_ReclaimOnResize)
{
@ -264,8 +264,8 @@ size_t RendererBase::FinalBufferSize() const { return FinalRowSize() *
size_t RendererBase::PixelSize() const { return NumChannels() * BytesPerChannel(); }
size_t RendererBase::GutterWidth() const { return m_GutterWidth; }
size_t RendererBase::DensityFilterOffset() const { return m_DensityFilterOffset; }
size_t RendererBase::TotalIterCount(size_t strips) const { return size_t(size_t(Round(ScaledQuality())) * FinalRasW() * FinalRasH() * strips); }//Use Round() because there can be some roundoff error when interpolating.
size_t RendererBase::ItersPerTemporalSample() const { return size_t(ceil(double(TotalIterCount(1)) / double(TemporalSamples()))); }//Temporal samples is used with animation, which doesn't support strips, so pass 1.
size_t RendererBase::TotalIterCount(size_t strips) const { return static_cast<size_t>(static_cast<size_t>(Round(ScaledQuality())) * FinalRasW() * FinalRasH() * strips); }//Use Round() because there can be some roundoff error when interpolating.
size_t RendererBase::ItersPerTemporalSample() const { return static_cast<size_t>(std::ceil(static_cast<double>(TotalIterCount(1)) / static_cast<double>(TemporalSamples()))); }//Temporal samples is used with animation, which doesn't support strips, so pass 1.
eProcessState RendererBase::ProcessState() const { return m_ProcessState; }
eProcessAction RendererBase::ProcessAction() const { return m_ProcessAction; }
EmberStats RendererBase::Stats() const { return m_Stats; }

View File

@ -114,7 +114,7 @@ public:
//First clear out any xforms that are not the final, and have a density of less than 0.001.
while (auto xform = ember.GetXform(i))
while (const auto xform = ember.GetXform(i))
{
if (xform->m_Weight < T(0.001))
{
@ -130,18 +130,17 @@ public:
//Now consider all xforms, including final.
i = 0;
while (auto xform = ember.GetTotalXform(i))
while (const auto xform = ember.GetTotalXform(i))
{
do
{
Variation<T>* var = nullptr;
Variation<T>* smallestVar = nullptr;
numVars = 0;
smallest = -1;
for (j = 0; j < xform->TotalVariationCount(); j++)
{
var = xform->GetVariation(j);
const auto var = xform->GetVariation(j);
if (var && var->m_Weight != 0.0)
{
@ -224,15 +223,15 @@ public:
for (size_t i = 0; i < ember.TotalXformCount(); i++)
{
auto xform1 = ember.GetTotalXform(i);
auto xform2 = mutation.GetTotalXform(i);
const auto xform1 = ember.GetTotalXform(i);
const auto xform2 = mutation.GetTotalXform(i);
if (xform1 && xform2)
{
for (size_t j = 0; j < xform1->TotalVariationCount(); j++)
{
Variation<T>* var1 = xform1->GetVariation(j);
Variation<T>* var2 = xform2->GetVariationById(var1->VariationId());
const auto var1 = xform1->GetVariation(j);
const auto var2 = xform2->GetVariationById(var1->VariationId());
if ((var1 == nullptr) ^ (var2 == nullptr))//If any of them are different, clear the first and copy all of the second and exit the while loop.
{
@ -255,8 +254,8 @@ public:
Random(mutation, useVars, sym, 2, maxVars);
//Which xform to mutate?
modXform = m_Rand.Rand(ember.TotalXformCount());
auto xform1 = ember.GetTotalXform(modXform);
auto xform2 = mutation.GetTotalXform(0);
const auto xform1 = ember.GetTotalXform(modXform);
const auto xform2 = mutation.GetTotalXform(0);
os << "mutate xform " << modXform << " coefs";
//If less than 3 xforms, then change only the translation part.
@ -279,14 +278,14 @@ public:
}
else if (mode == eMutateMode::MUTATE_POST_XFORMS)
{
bool same = (m_Rand.Rand() & 3) > 0;//25% chance of using the same post for all of them.
const auto same = (m_Rand.Rand() & 3) > 0;//25% chance of using the same post for all of them.
size_t b = 1 + m_Rand.Rand(6);
os << "mutate post xforms " << b << (same ? " same" : "");
for (size_t i = 0; i < ember.TotalXformCount(); i++)
{
bool copy = (i > 0) && same;
auto xform = ember.GetTotalXform(i);
const auto copy = (i > 0) && same;
const auto xform = ember.GetTotalXform(i);
if (copy)//Copy the post from the first xform to the rest of them.
{
@ -297,7 +296,7 @@ public:
//50% chance.
if (b & 1)
{
T f = T(M_PI) * m_Rand.Frand11<T>();
auto f = static_cast<T>(M_PI) * m_Rand.Frand11<T>();
T ra, rb, rd, re;
ra = (xform->m_Affine.A() * std::cos(f) + xform->m_Affine.B() * -std::sin(f));
rd = (xform->m_Affine.A() * std::sin(f) + xform->m_Affine.D() * std::cos(f));
@ -321,8 +320,8 @@ public:
//33% chance.
if (b & 2)
{
T f = T(0.2) + m_Rand.Frand01<T>();
T g = T(0.2) + m_Rand.Frand01<T>();
auto f = static_cast<T>(0.2) + m_Rand.Frand01<T>();
auto g = static_cast<T>(0.2) + m_Rand.Frand01<T>();
if (m_Rand.RandBit())
f = 1 / f;
@ -344,8 +343,8 @@ public:
if (b & 4)//16% chance.
{
T f = m_Rand.Frand11<T>();
T g = m_Rand.Frand11<T>();
const auto f = m_Rand.Frand11<T>();
const auto g = m_Rand.Frand11<T>();
xform->m_Affine.C(xform->m_Affine.C() - f);
xform->m_Affine.F(xform->m_Affine.F() - g);
xform->m_Post.C(xform->m_Post.C() + f);
@ -356,7 +355,7 @@ public:
}
else if (mode == eMutateMode::MUTATE_COLOR_PALETTE)
{
T s = m_Rand.Frand01<T>();
const auto s = m_Rand.Frand01<T>();
if (s < T(0.4))//Randomize xform color coords.
{
@ -401,8 +400,8 @@ public:
//Change all the coefs by a fraction of the random.
for (size_t x = 0; x < ember.TotalXformCount(); x++)
{
auto xform1 = ember.GetTotalXform(x);
auto xform2 = mutation.GetTotalXform(x);
const auto xform1 = ember.GetTotalXform(x);
const auto xform2 = mutation.GetTotalXform(x);
for (glm::length_t i = 0; i < 2; i++)
for (glm::length_t j = 0; j < 3; j++)
@ -432,7 +431,7 @@ public:
if (crossMode == eCrossMode::CROSS_NOT_SPECIFIED)
{
T s = m_Rand.Frand01<T>();
const auto s = m_Rand.Frand01<T>();
if (s < 0.1)
crossMode = eCrossMode::CROSS_UNION;
@ -558,7 +557,7 @@ public:
{
//Select the starting parent.
size_t ci;
uint startParent = m_Rand.RandBit();
auto startParent = m_Rand.RandBit();
os << " cmap_cross " << startParent << ":";
//Loop over the entries, switching to the other parent 1% of the time.
@ -651,7 +650,7 @@ public:
//Loop over xforms.
for (i = 0; i < ember.TotalXformCount(); i++)
{
auto xform = ember.GetTotalXform(i);
const auto xform = ember.GetTotalXform(i);
xform->m_Weight = T(1) / ember.TotalXformCount();
xform->m_ColorX = m_Rand.Frand01<T>();//Original pingponged between 0 and 1, which gives bad coloring. Ember does random instead.
xform->m_ColorY = m_Rand.Frand01<T>();//Will need to update this if 2D coordinates are ever supported.
@ -722,7 +721,7 @@ public:
if (var != -2)
{
//Pick a random variation and use a random weight from 0-1.
Variation<T>* v = m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand(varCount)), m_Rand.Frand<T>(T(0.001), 1));
auto v = m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand(varCount)), m_Rand.Frand<T>(static_cast<T>(0.001), 1));
if (v && !xform->AddVariation(v))
delete v;//It already existed and therefore was not added.
@ -730,7 +729,7 @@ public:
else
{
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
Variation<T>* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand<T>(T(0.001), 1));
auto v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand<T>(static_cast<T>(0.001), 1));
if (v && !xform->AddVariation(v))
delete v;
@ -760,12 +759,12 @@ public:
if (var != -2)
{
//Pick a random variation and use a random weight from 0-1.
xform->AddVariation(m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand(varCount)), m_Rand.Frand<T>(T(0.001), 1)));
xform->AddVariation(m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand(varCount)), m_Rand.Frand<T>(static_cast<T>(0.001), 1)));
}
else
{
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand<T>(T(0.001), 1)));
xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand<T>(static_cast<T>(0.001), 1)));
}
}
}
@ -865,16 +864,16 @@ public:
for (i = 0; i < m_FinalImage.size(); i++)
{
auto& p = m_FinalImage[i];
m_Hist[size_t((p.r * res) +
(p.g * res) * res +
(p.b * res) * res * res)]++;//A specific histogram index representing the sum of R,G,B values.
m_Hist[static_cast<size_t>((p.r * res) +
(p.g * res) * res +
(p.b * res) * res * res)]++;//A specific histogram index representing the sum of R,G,B values.
}
for (i = 0; i < res3; i++)
if (m_Hist[i])//The greater range of RGB values used...
hits++;
return T(hits / res3);//...the higher this returned ratio will be.
return static_cast<T>(hits / res3);//...the higher this returned ratio will be.
}
/// <summary>
@ -903,8 +902,8 @@ public:
ember.GetTotalXform(i)->m_ColorY = m_Rand.Frand01<T>();
}
auto xform0 = RandomXform(ember, -1);
auto xform1 = RandomXform(ember, ember.GetXformIndex(xform0));
const auto xform0 = RandomXform(ember, -1);
const auto xform1 = RandomXform(ember, ember.GetXformIndex(xform0));
if (xform0 && (m_Rand.RandBit()))
{
@ -936,10 +935,9 @@ public:
if (i != excluded)
{
auto xform = ember.GetTotalXform(i);
if (xform->m_Weight > 0)
return xform;
if (const auto xform = ember.GetTotalXform(i))
if (xform->m_Weight > 0)
return xform;
}
}
@ -963,10 +961,10 @@ public:
//the result xforms before rotate is called.
for (size_t i = 0; i < ember.TotalXformCount(); i++)
{
auto xform1 = ember.GetTotalXform(i);
auto xform2 = rotated.GetTotalXform(i);
const auto xform1 = ember.GetTotalXform(i);
const auto xform2 = rotated.GetTotalXform(i);
if (!xform1->m_Motion.empty())
if (xform1 && xform2 && !xform1->m_Motion.empty())
xform2->ApplyMotion(*xform1, blend);
}
@ -998,10 +996,10 @@ public:
for (i = 0; i < m_EdgePrealign[si].TotalXformCount(); i++)
{
auto xform = embers[si].GetTotalXform(i);
auto prealignxform = m_EdgePrealign[si].GetTotalXform(i);
const auto xform = embers[si].GetTotalXform(i);
const auto prealignxform = m_EdgePrealign[si].GetTotalXform(i);
if (!xform->m_Motion.empty())
if (xform && prealignxform && !xform->m_Motion.empty())
prealignxform->ApplyMotion(*xform, blend);//Apply motion parameters to result.xform[i] using blend parameter.
}
}
@ -1024,7 +1022,7 @@ public:
//Rotate the aligned xforms.
if (rotations)
{
auto cwblend = cw ? blend : -blend;
const auto cwblend = cw ? blend : -blend;
m_EdgeSpun[0].RotateAffines(cwblend * (360 * rotations));
m_EdgeSpun[1].RotateAffines(cwblend * (360 * rotations));
}
@ -1050,8 +1048,8 @@ public:
/// <param name="cw">True to rotate clockwise, else rotate counter clockwise. Ignored if rotations is 0.</param>
void Spin(Ember<T>& parent, Ember<T>* templ, Ember<T>& result, size_t frame, T blend, bool cw)
{
auto cwblend = cw ? blend : -blend;
string temp = "rotate " + std::to_string(cwblend * 360.0);
const auto cwblend = cw ? blend : -blend;
const string temp = "rotate " + std::to_string(cwblend * 360.0);
//Spin the parent blend degrees.
Loop(parent, result, blend, cw);
@ -1068,6 +1066,8 @@ public:
result.m_Edits = m_EmberToXml.CreateNewEditdoc(&parent, nullptr, temp, m_Nick, m_Url, m_Id, m_Comment, m_SheepGen, m_SheepId);
//Subpixel jitter.
Offset(result, m_OffsetX, m_OffsetY);
//Need to set these to be equal so rendering works correctly for off center embers.
result.m_RotCenterY = result.m_CenterY;
//Make the name of the flame the time.
result.m_Name = std::to_string(result.m_Time);
}
@ -1088,8 +1088,8 @@ public:
/// <param name="cw">True to rotate clockwise, else rotate counter clockwise. Ignored if rotations is 0.</param>
void SpinInter(Ember<T>* parents, Ember<T>* templ, Ember<T>& result, size_t frame, bool seqFlag, T blend, size_t rotations, bool cw)
{
auto cwblend = cw ? blend : -blend;
string temp = "interpolate " + std::to_string(cwblend * 360.0);
const auto cwblend = cw ? blend : -blend;
const string temp = "interpolate " + std::to_string(cwblend * 360.0);
//Interpolate between spun parents.
Edge(parents, result, blend, rotations, cw, seqFlag);
@ -1106,6 +1106,8 @@ public:
result.m_Edits = m_EmberToXml.CreateNewEditdoc(&parents[0], &parents[1], temp, m_Nick, m_Url, m_Id, m_Comment, m_SheepGen, m_SheepId);
//Subpixel jitter.
Offset(result, m_OffsetX, m_OffsetY);
//Need to set these to be equal so rendering works correctly for off center embers.
result.m_RotCenterY = result.m_CenterY;
//Make the name of the flame the time.
result.m_Name = std::to_string(result.m_Time);
}
@ -1216,9 +1218,9 @@ public:
void RotateOldCenterBy(T& newCenterX, T& newCenterY, T oldCenterX, T oldCenterY, T by)
{
T r[2];
T th = by * 2 * T(M_PI) / 360;
T c = std::cos(th);
T s = -std::sin(th);
const T th = by * 2 * static_cast<T>(M_PI) / 360;
const T c = std::cos(th);
const T s = -std::sin(th);
newCenterX -= oldCenterX;
newCenterY -= oldCenterY;
r[0] = c * newCenterX - s * newCenterY;
@ -1258,11 +1260,11 @@ public:
//params.m_OneRowDiv2 = m_Renderer->CoordMap().OneRow() / 2;
size_t bv = m_Iterator->Iterate(ember, params, ctr, m_Samples.data(), m_Rand);//Use a special fuse of 20, all other calls to this will use 15, or 100.
if (bv / T(samples) > eps)
if (bv / static_cast<T>(samples) > eps)
eps = 3 * bv / T(samples);
if (eps > T(0.3))
eps = T(0.3);
if (eps > static_cast<T>(0.3))
eps = static_cast<T>(0.3);
lowTarget = static_cast<size_t>(samples * eps);
highTarget = samples - lowTarget;

View File

@ -51,7 +51,7 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
SpatialFilter(eSpatialFilterType filterType, T support, T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
SpatialFilter(eSpatialFilterType filterType, T support, T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
{
m_FilterType = filterType;
m_Support = support;
@ -115,9 +115,9 @@ public:
return;
}
T fw = T(2.0) * m_Support * m_Supersample * m_FilterRadius / m_PixelAspectRatio;
T fw = static_cast<T>(2) * m_Support * m_Supersample * m_FilterRadius / m_PixelAspectRatio;
T adjust, ii, jj;
int fwidth = int(fw) + 1;
int fwidth = static_cast<int>(fw) + 1;
int i, j;
//Make sure the filter kernel has same parity as oversample.
@ -128,7 +128,7 @@ public:
if (fw > 0.0)
adjust = m_Support * fwidth / fw;
else
adjust = T(1.0);
adjust = static_cast<T>(1);
m_Filter.resize(fwidth * fwidth);
@ -138,8 +138,8 @@ public:
for (j = 0; j < fwidth; j++)
{
//Calculate the function inputs for the kernel function.
ii = ((T(2.0) * i + T(1.0)) / T(fwidth) - T(1.0)) * adjust;
jj = ((T(2.0) * j + T(1.0)) / T(fwidth) - T(1.0)) * adjust;
ii = ((static_cast<T>(2) * i + static_cast<T>(1)) / static_cast<T>(fwidth) - static_cast<T>(1)) * adjust;
jj = ((static_cast<T>(2) * j + static_cast<T>(1)) / static_cast<T>(fwidth) - static_cast<T>(1)) * adjust;
//Adjust for aspect ratio.
jj /= m_PixelAspectRatio;
m_Filter[i + j * fwidth] = Filter(ii) * Filter(jj);//Call virtual Filter(), implemented in specific derived filter classes.
@ -153,7 +153,7 @@ public:
break;
}
m_FilterRadius += T(0.01);//Values were too small.
m_FilterRadius += static_cast<T>(0.01);//Values were too small.
}
while (1);
}
@ -208,7 +208,7 @@ protected:
/// <returns>The calculated value</returns>
static T Sinc(T x)
{
x *= T(M_PI);
x *= static_cast<T>(M_PI);
if (x != 0)
return std::sin(x) / x;
@ -224,7 +224,7 @@ private:
bool Normalize()
{
size_t i;
T t = T(0.0);
T t = 0;
for (i = 0; i < m_Filter.size(); i++)
t += m_Filter[i];
@ -232,7 +232,7 @@ private:
if (t == 0.0 || std::isinf(t) || std::isnan(t) || !std::isnormal(t))
return false;
t = T(1.0 / t);
t = static_cast<T>(1 / t);
for (i = 0; i < m_Filter.size(); i++)
{
@ -268,8 +268,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
GaussianFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { }
GaussianFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER, static_cast<T>(1.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Gaussian filter to t parameter and return.
@ -278,7 +278,7 @@ public:
/// <returns>The filtered value</returns>
virtual T Filter(T t) const override
{
return T(std::exp(-2 * t * t) * std::sqrt(2 / M_PI));
return static_cast<T>(std::exp(-2 * t * t) * std::sqrt(2 / M_PI));
}
};
@ -296,8 +296,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
HermiteFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::HERMITE_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
HermiteFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::HERMITE_SPATIAL_FILTER, static_cast<T>(1), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Hermite filter to t parameter and return.
@ -311,7 +311,7 @@ public:
t = -t;
if (t < 1)
return T((2.0 * t - 3.0) * t * t + 1.0);
return static_cast<T>((2 * t - 3) * t * t + 1);
return 0;
}
@ -331,8 +331,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
BoxFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::BOX_SPATIAL_FILTER, T(0.5), filterRadius, superSample, pixelAspectRatio) { }
BoxFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::BOX_SPATIAL_FILTER, static_cast<T>(0.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Box filter to t parameter and return.
@ -341,7 +341,7 @@ public:
/// <returns>The filtered value</returns>
virtual T Filter(T t) const override
{
if ((t > T(-0.5)) && (t <= T(0.5)))
if ((t > static_cast<T>(-0.5)) && (t <= static_cast<T>(0.5)))
return 1;
return 0;
@ -362,8 +362,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
TriangleFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::TRIANGLE_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
TriangleFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::TRIANGLE_SPATIAL_FILTER, static_cast<T>(1), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Triangle filter to t parameter and return.
@ -396,8 +396,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
BellFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::BELL_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { }
BellFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::BELL_SPATIAL_FILTER, static_cast<T>(1.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Bell filter to t parameter and return.
@ -410,13 +410,13 @@ public:
if (t < 0)
t = -t;
if (t < T(0.5))
return T(0.75 - (t * t));
if (t < static_cast<T>(0.5))
return static_cast<T>(0.75 - (t * t));
if (t < T(1.5))
if (t < static_cast<T>(1.5))
{
t = T(t - 1.5);
return T(0.5 * (t * t));
t = static_cast<T>(t - 1.5);
return static_cast<T>(0.5 * (t * t));
}
return 0;
@ -437,8 +437,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
BsplineFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::BSPLINE_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
BsplineFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::BSPLINE_SPATIAL_FILTER, static_cast<T>(2), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply B Spline filter to t parameter and return.
@ -456,12 +456,12 @@ public:
if (t < 1)
{
tt = t * t;
return T((0.5 * tt * t) - tt + (2.0 / 3.0));
return static_cast<T>((0.5 * tt * t) - tt + (2.0 / 3.0));
}
else if (t < 2)
{
t = 2 - t;
return T((1.0 / 6.0) * (t * t * t));
return static_cast<T>((1.0 / 6.0) * (t * t * t));
}
return 0;
@ -482,8 +482,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
Lanczos3Filter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::LANCZOS3_SPATIAL_FILTER, T(3.0), filterRadius, superSample, pixelAspectRatio) { }
Lanczos3Filter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::LANCZOS3_SPATIAL_FILTER, static_cast<T>(3), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Lanczos 3 filter to t parameter and return.
@ -516,8 +516,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
Lanczos2Filter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::LANCZOS2_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
Lanczos2Filter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::LANCZOS2_SPATIAL_FILTER, static_cast<T>(2), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Lanczos 2 filter to t parameter and return.
@ -550,8 +550,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
MitchellFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::MITCHELL_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
MitchellFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::MITCHELL_SPATIAL_FILTER, static_cast<T>(2), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Mitchell filter to t parameter and return.
@ -561,25 +561,25 @@ public:
virtual T Filter(T t) const override
{
T tt = t * t;
const T b = T(1.0 / 3.0);
const T c = T(1.0 / 3.0);
const T b = static_cast<T>(1.0 / 3.0);
const T c = static_cast<T>(1.0 / 3.0);
if (t < 0)
t = -t;
if (t < 1)
{
t = T(((12.0 - 9.0 * b - 6.0 * c) * (t * tt))
+ ((-18.0 + 12.0 * b + 6.0 * c) * tt)
+ (6.0 - 2 * b));
t = static_cast<T>(((12.0 - 9.0 * b - 6.0 * c) * (t * tt))
+ ((-18.0 + 12.0 * b + 6.0 * c) * tt)
+ (6.0 - 2 * b));
return t / 6;
}
else if (t < 2)
{
t = T(((-1.0 * b - 6.0 * c) * (t * tt))
+ ((6.0 * b + 30.0 * c) * tt)
+ ((-12.0 * b - 48.0 * c) * t)
+ (8.0 * b + 24 * c));
t = static_cast<T>(((-1.0 * b - 6.0 * c) * (t * tt))
+ ((6.0 * b + 30.0 * c) * tt)
+ ((-12.0 * b - 48.0 * c) * t)
+ (8.0 * b + 24 * c));
return t / 6;
}
@ -601,8 +601,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
BlackmanFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::BLACKMAN_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
BlackmanFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::BLACKMAN_SPATIAL_FILTER, static_cast<T>(1), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Blackman filter to t parameter and return.
@ -611,7 +611,7 @@ public:
/// <returns>The filtered value</returns>
virtual T Filter(T t) const override
{
return T(0.42 + 0.5 * std::cos(M_PI * t) + 0.08 * std::cos(2 * M_PI * t));
return static_cast<T>(0.42 + 0.5 * std::cos(M_PI * t) + 0.08 * std::cos(2 * M_PI * t));
}
};
@ -629,8 +629,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
CatromFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::CATROM_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
CatromFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::CATROM_SPATIAL_FILTER, static_cast<T>(2), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Catmull-Rom filter to t parameter and return.
@ -643,16 +643,16 @@ public:
return 0;
if (t < -1)
return T(0.5 * (4 + t * (8 + t * (5 + t))));
return static_cast<T>(0.5 * (4 + t * (8 + t * (5 + t))));
if (t < 0)
return T(0.5 * (2 + t * t * (-5 - 3 * t)));
return static_cast<T>(0.5 * (2 + t * t * (-5 - 3 * t)));
if (t < 1)
return T(0.5 * (2 + t * t * (-5 + 3 * t)));
return static_cast<T>(0.5 * (2 + t * t * (-5 + 3 * t)));
if (t < 2)
return T(0.5 * (4 + t * (-8 + t * (5 - t))));
return static_cast<T>(0.5 * (4 + t * (-8 + t * (5 - t))));
return 0;
}
@ -672,8 +672,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
HammingFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::HAMMING_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
HammingFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::HAMMING_SPATIAL_FILTER, static_cast<T>(1), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Hamming filter to t parameter and return.
@ -682,7 +682,7 @@ public:
/// <returns>The filtered value</returns>
virtual T Filter(T t) const override
{
return T(0.54 + 0.46 * std::cos(M_PI * t));
return static_cast<T>(0.54 + 0.46 * std::cos(M_PI * t));
}
};
@ -700,8 +700,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
HanningFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::HANNING_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
HanningFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::HANNING_SPATIAL_FILTER, static_cast<T>(1), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Hanning filter to t parameter and return.
@ -710,7 +710,7 @@ public:
/// <returns>The filtered value</returns>
virtual T Filter(T t) const override
{
return T(0.5 + 0.5 * std::cos(M_PI * t));
return static_cast<T>(0.5 + 0.5 * std::cos(M_PI * t));
}
};
@ -728,8 +728,8 @@ public:
/// <param name="filterRadius">The filter radius</param>
/// <param name="superSample">The supersample of the ember being rendered</param>
/// <param name="pixelAspectRatio">The pixel aspect ratio being used to render. Default: 1.</param>
QuadraticFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(eSpatialFilterType::QUADRATIC_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { }
QuadraticFilter(T filterRadius, size_t superSample, T pixelAspectRatio = static_cast<T>(1))
: SpatialFilter<T>(eSpatialFilterType::QUADRATIC_SPATIAL_FILTER, static_cast<T>(1.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary>
/// Apply Quadratic filter to t parameter and return.
@ -742,13 +742,13 @@ public:
return 0.0;
if (t < -0.5)
return T(0.5 * (t + 1.5) * (t + 1.5));
return static_cast<T>(0.5 * (t + 1.5) * (t + 1.5));
if (t < 0.5)
return T(0.75 - (t * t));
return static_cast<T>(0.75 - (t * t));
if (t < 1.5)
return T(0.5 * (t - 1.5) * (t - 1.5));
return static_cast<T>(0.5 * (t - 1.5) * (t - 1.5));
return 0;
}

View File

@ -115,11 +115,11 @@ T Spline<T>::Interpolate(T newX)
while (j < n && newX > vals[j + 1].x)
j++;
auto xmxj = newX - vals[j].x;
auto output = a[j] * (xmxj * xmxj * xmxj) +
b[j] * (xmxj * xmxj) +
c[j] * xmxj +
d[j];
const auto xmxj = newX - vals[j].x;
const auto output = a[j] * (xmxj * xmxj * xmxj) +
b[j] * (xmxj * xmxj) +
c[j] * xmxj +
d[j];
return output;
}

View File

@ -46,7 +46,8 @@ public:
/// <param name="filterType">Type of the filter.</param>
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</param>
/// <param name="filterWidth">The width of the filter.</param>
TemporalFilter(eTemporalFilterType filterType, size_t temporalSamples, T filterWidth)
/// <param name="filterExp">The filter exponent. Unused except with ExpTemporalFilter, but needed to prevent equality tests from failing.</param>
TemporalFilter(eTemporalFilterType filterType, size_t temporalSamples, T filterWidth, T filterExp)
{
size_t i, steps = temporalSamples;
m_TemporalSamples = temporalSamples;
@ -54,7 +55,7 @@ public:
m_Deltas.resize(steps);
m_Filter.resize(steps);
m_FilterType = filterType;
m_FilterExp = 1;
m_FilterExp = filterExp;//Always assign this to prevent excessive recreates in Renderer::CreateTemporalFilter().
if (steps == 1)
{
@ -66,7 +67,7 @@ public:
{
//Define the temporal deltas.
for (i = 0; i < steps; i++)
m_Deltas[i] = (T(i) / T(steps - 1) - T(0.5)) * filterWidth;
m_Deltas[i] = (static_cast<T>(i) / static_cast<T>(steps - 1) - static_cast<T>(0.5)) * filterWidth;
}
}
@ -131,6 +132,7 @@ public:
for (i = 0; i < m_Filter.size(); i++)
{
ss << "Filter[" << i << "]: " << m_Filter[i] << "\n";
//ss << m_Filter[i] << "\n";
}
return ss.str();
@ -166,7 +168,7 @@ protected:
m_SumFilt /= Size();
}
T m_SumFilt;//The sum of all filter values.
T m_SumFilt = 1;//The sum of all filter values.
T m_FilterWidth;
T m_FilterExp;
size_t m_TemporalSamples;
@ -188,9 +190,9 @@ public:
/// </summary>
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</param>
/// <param name="filterWidth">The width of the filter.</param>
/// <param name="filterExp">The filter exp.</param>
ExpTemporalFilter(size_t temporalSamples, T filterWidth, T filterExp)
: TemporalFilter<T>(eTemporalFilterType::BOX_TEMPORAL_FILTER, temporalSamples, filterWidth)
/// <param name="filterExp">The filter exponent.</param>
ExpTemporalFilter(size_t temporalSamples, T filterWidth, T filterExp = 1)
: TemporalFilter<T>(eTemporalFilterType::EXP_TEMPORAL_FILTER, temporalSamples, filterWidth, filterExp)
{
if (Size() > 1)
{
@ -199,9 +201,9 @@ public:
for (size_t i = 0; i < Size(); i++)
{
if (filterExp >= 0)
slpx = (T(i) + 1) / Size();
slpx = (static_cast<T>(i) + 1) / Size();
else
slpx = T(Size() - i) / Size();
slpx = static_cast<T>(Size() - i) / Size();
//Scale the color based on these values.
m_Filter[i] = std::pow(slpx, fabs(filterExp));
@ -211,7 +213,6 @@ public:
maxFilt = m_Filter[i];
}
m_FilterExp = filterExp;
FinishFilter(maxFilt);
}
}
@ -230,12 +231,13 @@ public:
/// </summary>
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</param>
/// <param name="filterWidth">The width of the filter.</param>
GaussianTemporalFilter(size_t temporalSamples, T filterWidth)
: TemporalFilter<T>(eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER, temporalSamples, filterWidth)
/// <param name="filterExp">Unused, but needed to prevent equality tests from failing.</param>
GaussianTemporalFilter(size_t temporalSamples, T filterWidth, T filterExp)
: TemporalFilter<T>(eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER, temporalSamples, filterWidth, filterExp)
{
if (Size() > 1)
{
T maxFilt = 0, halfSteps = T(Size()) / T(2);
T maxFilt = 0, halfSteps = static_cast<T>(Size()) / static_cast<T>(2);
GaussianFilter<T> gaussian(1, 1);//Just pass dummy values, they are unused in this case.
for (size_t i = 0; i < Size(); i++)
@ -265,8 +267,9 @@ public:
/// </summary>
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</param>
/// <param name="filterWidth">The width of the filter.</param>
BoxTemporalFilter(size_t temporalSamples, T filterWidth)
: TemporalFilter<T>(eTemporalFilterType::BOX_TEMPORAL_FILTER, temporalSamples, filterWidth)
/// <param name="filterExp">Unused, but needed to prevent equality tests from failing.</param>
BoxTemporalFilter(size_t temporalSamples, T filterWidth, T filterExp)
: TemporalFilter<T>(eTemporalFilterType::BOX_TEMPORAL_FILTER, temporalSamples, filterWidth, filterExp)
{
if (Size() > 1)
{
@ -291,20 +294,20 @@ public:
/// <param name="filterType">Type of the filter</param>
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</param>
/// <param name="filterWidth">The width of the filter</param>
/// <param name="filterExp">The filter exp, only used with Exp filter, otherwise ignored.</param>
/// <param name="filterExp">The filter exp, only used with Exp filter, otherwise unused but needed to prevent equality tests from failing.</param>
/// <returns>A pointer to the newly created filter object</returns>
static TemporalFilter<T>* Create(eTemporalFilterType filterType, size_t temporalSamples, T filterWidth, T filterExp = 1)
static TemporalFilter<T>* Create(eTemporalFilterType filterType, size_t temporalSamples, T filterWidth, T filterExp)
{
TemporalFilter<T>* filter = nullptr;
switch (filterType)
{
case EmberNs::eTemporalFilterType::BOX_TEMPORAL_FILTER:
filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth);
filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth, filterExp);
break;
case EmberNs::eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER:
filter = new GaussianTemporalFilter<T>(temporalSamples, filterWidth);
filter = new GaussianTemporalFilter<T>(temporalSamples, filterWidth, filterExp);
break;
case EmberNs::eTemporalFilterType::EXP_TEMPORAL_FILTER:
@ -312,7 +315,7 @@ public:
break;
default:
filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth);//Default to box if bad enum passed in.
filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth, filterExp);//Default to box if bad enum passed in.
break;
}

View File

@ -48,7 +48,7 @@ public:
double Toc(const char* str = nullptr, bool fullString = false)
{
m_EndTime = NowMsD();
double ms = ElapsedTime();
const auto ms = ElapsedTime();
if (str)
{
@ -91,13 +91,13 @@ public:
{
stringstream ss;
double x = ms / 1000;
double secs = fmod(x, 60);
const auto secs = fmod(x, 60);
x /= 60;
double mins = fmod(x, 60);
const auto mins = fmod(x, 60);
x /= 60;
double hours = fmod(x, 24);
const auto hours = fmod(x, 24);
x /= 24;
double days = x;
const auto days = x;
if (days >= 1)
ss << static_cast<int>(days) << "d ";

View File

@ -954,20 +954,20 @@ static string Trim(const string& str, char ch = ' ')
/// <returns>The vector containing the split tokens</returns>
static vector<std::string> Split(const string& str, const string& del, bool removeEmpty = false)
{
int current = 0;
int next = -1;
size_t current = 0;
size_t next = std::numeric_limits<size_t>::max();
vector<string> vec;
do
{
current = next + 1;
next = int(str.find_first_of(del, current));
next = str.find_first_of(del, current);
string ent(Trim(str.substr(current, next - current)));
if (!removeEmpty || ent.length() > 0)
vec.push_back(ent);
}
while (next != int(string::npos));
while (next != string::npos);
return vec;
}

View File

@ -2283,10 +2283,8 @@ public:
vec.reserve(m_Params.size());
for (auto& param : m_Params)
{
if ((includePrecalcs && param.IsPrecalc()) || !param.IsPrecalc())
vec.push_back(param.Name());
}
return vec;
}
@ -2305,12 +2303,8 @@ public:
string index = os2.str();
for (auto& param : m_Params)
{
if (param.IsState())
{
os << "\n\treal_t " << param.Name() << index;
}
}
return os.str();
}
@ -2324,12 +2318,8 @@ public:
size_t count = 0;
for (auto& param : m_Params)
{
if (param.IsState())
{
count++;
}
}
return count;
}
@ -2344,12 +2334,8 @@ public:
virtual void InitStateVars(T* t, size_t& index) override
{
for (auto& param : m_Params)
{
if (param.IsState())
{
t[index++] = param.ParamVal();
}
}
}
/// <summary>

View File

@ -661,7 +661,7 @@ int VariationList<T>::GetVariationIndex(const string& name) const
{
for (size_t i = 0; i < m_Variations.size() && m_Variations[i]; i++)
if (!_stricmp(name.c_str(), m_Variations[i]->Name().c_str()))
return int(i);
return static_cast<int>(i);
return -1;
}

View File

@ -487,7 +487,7 @@ bool XmlToEmber<T>::Parse(byte* buf, const char* filename, C<Ember<T>, Alloc>& e
xmlFreeDoc(doc);
emberSize = embers.size();
auto first = embers.begin();
const auto first = embers.begin();
//t.Toc("ScanForEmberNodes");
@ -519,7 +519,7 @@ bool XmlToEmber<T>::Parse(byte* buf, const char* filename, C<Ember<T>, Alloc>& e
if (emberSize > 1)
{
auto prev = embers.begin();
auto second = Advance(embers.begin(), 1);
const auto second = Advance(embers.begin(), 1);
for (auto it = second; it != embers.end(); ++it)
{
@ -633,7 +633,7 @@ void XmlToEmber<T>::ScanForEmberNodes(xmlNode* curNode, const char* parentFile,
if (currentEmber.PaletteIndex() != -1)
{
if (auto pal = m_PaletteList->GetPaletteByFilename(m_PaletteList->m_DefaultFilename, currentEmber.PaletteIndex()))
if (const auto pal = m_PaletteList->GetPaletteByFilename(m_PaletteList->m_DefaultFilename, currentEmber.PaletteIndex()))
currentEmber.m_Palette = *pal;
else
AddToReport(string(loc) + " : Error assigning palette with index " + std::to_string(currentEmber.PaletteIndex()));
@ -667,11 +667,11 @@ void XmlToEmber<T>::ScanForEmberNodes(xmlNode* curNode, const char* parentFile,
/// <returns>The name value if they matched, else nullptr.</returns>
static const char* CheckNameVal(xmlNode* node, const char* name)
{
if (auto att = node->properties)
if (const auto att = node->properties)
{
if (!Compare(att->name, "name"))
{
if (auto attStr = XC(xmlGetProp(node, att->name)))
if (const auto attStr = XC(xmlGetProp(node, att->name)))
{
if (!Compare(attStr, name))
{
@ -707,16 +707,10 @@ static xmlNode* CheckNodeName(xmlNode* node, const char* name)
/// <returns>The value of the name field if found, else nullptr.</returns>
static const char* GetNameVal(xmlNode* node, const char* name = "name")
{
if (auto att = node->properties)
{
if (const auto att = node->properties)
if (!Compare(att->name, name ? name : "name"))
{
if (auto attStr = XC(xmlGetProp(node, att->name)))
{
if (const auto attStr = XC(xmlGetProp(node, att->name)))
return CCX(attStr);
}
}
}
return nullptr;
};
@ -730,15 +724,9 @@ static const char* GetNameVal(xmlNode* node, const char* name = "name")
static xmlNode* GetChildNode(xmlNode* node, const char* name)
{
for (auto childNode = node->children; childNode; childNode = childNode->next)
{
if (childNode->type == XML_ELEMENT_NODE)
{
if (CheckNameVal(childNode, name))
{
return childNode;
}
}
}
return nullptr;
};
@ -752,15 +740,9 @@ static xmlNode* GetChildNode(xmlNode* node, const char* name)
static xmlNode* GetChildNodeByNodeName(xmlNode* node, const char* name)
{
for (auto childNode = node->children; childNode; childNode = childNode->next)
{
if (childNode->type == XML_ELEMENT_NODE)
{
if (auto node = CheckNodeName(childNode, name))
{
if (const auto node = CheckNodeName(childNode, name))
return node;
}
}
}
return nullptr;
};
@ -779,15 +761,15 @@ bool XmlToEmber<T>::ParseAndAssignContent(xmlNode* node, const char* fieldname,
{
bool ret = false;
if (auto att = node->properties)
if (const auto att = node->properties)
{
if (!Compare(att->name, fieldname))
{
if (auto attStr = XC(xmlGetProp(node, att->name)))
if (const auto attStr = XC(xmlGetProp(node, att->name)))
{
if (!fieldnameval || !Compare(attStr, fieldnameval))
{
if (auto cont = xmlNodeGetContent(node))
if (const auto cont = xmlNodeGetContent(node))
{
istringstream istr(CCX(cont));
istr >> val;
@ -814,15 +796,15 @@ bool XmlToEmber<T>::ParseAndAssignContent(xmlNode* node, const char* fieldname,
{
bool ret = false;
if (auto att = node->properties)
if (const auto att = node->properties)
{
if (!Compare(att->name, fieldname))
{
if (auto attStr = XC(xmlGetProp(node, att->name)))
if (const auto attStr = XC(xmlGetProp(node, att->name)))
{
if (!fieldnameval || !Compare(attStr, fieldnameval))
{
if (auto cont = xmlNodeGetContent(node))
if (const auto cont = xmlNodeGetContent(node))
{
val = CX(cont);
return true;
@ -863,10 +845,10 @@ void XmlToEmber<T>::ScanForChaosNodes(xmlNode* curNode, const char* parentFile,
if (!useDefaults)
currentEmber.Clear(false);
if (auto embername = GetNameVal(thisNode, "name"))
if (const auto embername = GetNameVal(thisNode, "name"))
currentEmber.m_Name = embername;
auto childNode = thisNode;
const auto childNode = thisNode;
bool ret = true;
parseEmberSuccess = ParseEmberElementFromChaos(childNode, currentEmber);
@ -916,7 +898,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
att = emberNode->properties;//The top level element is a ember element, read the attributes of it and store them.
auto variationsfunc = [&](const string & prefix, const char* nodename, xmlNode * node, Xform<T>& xf, std::vector<std::string>& alliterweights)
{
if (auto transformsChildNode = GetChildNode(node, nodename))
if (const auto transformsChildNode = GetChildNode(node, nodename))
{
for (auto variationNode = transformsChildNode->children; variationNode; variationNode = variationNode->next)
{
@ -936,9 +918,9 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
if (!varname.empty())
{
T weight = 1;
string corrvarname = GetCorrectedVariationName(m_BadVariationNames, varname);
auto corrwprefix = !StartsWith(corrvarname, prefix) ? prefix + corrvarname : corrvarname;
const T weight = 1;
const auto corrvarname = GetCorrectedVariationName(m_BadVariationNames, varname);
const auto corrwprefix = !StartsWith(corrvarname, prefix) ? prefix + corrvarname : corrvarname;
if (auto var = m_VariationList->GetVariation(corrwprefix))
{
@ -952,21 +934,21 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
if (auto paramsNode = GetChildNodeByNodeName(variationNode, "params"))
{
auto parvar = dynamic_cast<ParametricVariation<T>*>(varCopy);
const auto parvar = dynamic_cast<ParametricVariation<T>*>(varCopy);
for (auto paramsChildNode = paramsNode->children; paramsChildNode; paramsChildNode = paramsChildNode->next)
{
if (paramsChildNode->type == XML_ELEMENT_NODE)
{
if (auto paramname = GetNameVal(paramsChildNode))
if (const auto paramname = GetNameVal(paramsChildNode))
{
T val = 1;
if (auto paramCurveChildNode = GetChildNodeByNodeName(paramsChildNode, "curve"))
if (const auto paramCurveChildNode = GetChildNodeByNodeName(paramsChildNode, "curve"))
{
if (auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
if (const auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
{
if (auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
if (const auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
{
if (paramCurveValuesContentChildNode->children)
{
@ -1031,20 +1013,20 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
if (auto transformChildNode = GetChildNodeByNodeName(node, "flam3_transform"))
{
found = true;
auto itername = GetNameVal(node, "name");
const auto itername = GetNameVal(node, "name");
xf.m_Name = itername;
if (auto affineChildNode = GetChildNode(transformChildNode, "Pre affine"))
if (const auto affineChildNode = GetChildNode(transformChildNode, "Pre affine"))
{
std::string offsetstr;
double xangle = 0, xlength = 1, yangle = 90, ylength = 1, xoffset = 0, yoffset = 0;
if (auto xangleChildNode = GetChildNode(affineChildNode, "x_axis_angle"))
if (auto paramCurveChildNode = GetChildNodeByNodeName(xangleChildNode, "curve"))
if (const auto xangleChildNode = GetChildNode(affineChildNode, "x_axis_angle"))
if (const auto paramCurveChildNode = GetChildNodeByNodeName(xangleChildNode, "curve"))
{
if (auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
if (const auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
{
if (auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
if (const auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
{
if (paramCurveValuesContentChildNode->children)
{
@ -1058,15 +1040,15 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
else
ParseAndAssignContent(xangleChildNode, "name", "x_axis_angle", xangle);
if (auto xlengthChildNode = GetChildNode(affineChildNode, "x_axis_length"))
if (const auto xlengthChildNode = GetChildNode(affineChildNode, "x_axis_length"))
if (ParseAndAssignContent(xlengthChildNode, "name", "x_axis_length", xlength)) {}
if (auto yangleChildNode = GetChildNode(affineChildNode, "y_axis_angle"))
if (auto paramCurveChildNode = GetChildNodeByNodeName(yangleChildNode, "curve"))
if (const auto yangleChildNode = GetChildNode(affineChildNode, "y_axis_angle"))
if (const auto paramCurveChildNode = GetChildNodeByNodeName(yangleChildNode, "curve"))
{
if (auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
if (const auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
{
if (auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
if (const auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
{
if (paramCurveValuesContentChildNode->children)
{
@ -1080,10 +1062,10 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
else
ParseAndAssignContent(yangleChildNode, "name", "y_axis_angle", yangle);
if (auto ylengthChildNode = GetChildNode(affineChildNode, "y_axis_length"))
if (const auto ylengthChildNode = GetChildNode(affineChildNode, "y_axis_length"))
if (ParseAndAssignContent(ylengthChildNode, "name", "y_axis_length", ylength)) {}
if (auto offsetChildNode = GetChildNode(affineChildNode, "offset"))
if (const auto offsetChildNode = GetChildNode(affineChildNode, "offset"))
if (ParseAndAssignContent(offsetChildNode, "name", "offset", offsetstr))
{
istringstream istr(offsetstr);
@ -1104,18 +1086,18 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
xf.m_Affine.F(o2);
}
if (auto affineChildNode = GetChildNode(transformChildNode, "Post affine"))
if (const auto affineChildNode = GetChildNode(transformChildNode, "Post affine"))
{
std::string offsetstr;
double xangle = 0, xlength = 1, yangle = 90, ylength = 1, xoffset = 0, yoffset = 0;
if (auto xangleChildNode = GetChildNode(affineChildNode, "x_axis_angle"))
if (const auto xangleChildNode = GetChildNode(affineChildNode, "x_axis_angle"))
if (!ParseAndAssignContent(xangleChildNode, "name", "x_axis_angle", xangle))
if (auto paramCurveChildNode = GetChildNodeByNodeName(affineChildNode, "curve"))
if (const auto paramCurveChildNode = GetChildNodeByNodeName(affineChildNode, "curve"))
{
if (auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
if (const auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
{
if (auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
if (const auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
{
if (paramCurveValuesContentChildNode->children)
{
@ -1127,15 +1109,15 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
}
}
if (auto xlengthChildNode = GetChildNode(affineChildNode, "x_axis_length"))
if (const auto xlengthChildNode = GetChildNode(affineChildNode, "x_axis_length"))
if (ParseAndAssignContent(xlengthChildNode, "name", "x_axis_length", xlength)) {}
if (auto yangleChildNode = GetChildNode(affineChildNode, "y_axis_angle"))
if (auto paramCurveChildNode = GetChildNodeByNodeName(yangleChildNode, "curve"))
if (const auto yangleChildNode = GetChildNode(affineChildNode, "y_axis_angle"))
if (const auto paramCurveChildNode = GetChildNodeByNodeName(yangleChildNode, "curve"))
{
if (auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
if (const auto paramCurveValuesChildNode = GetChildNode(paramCurveChildNode, "values"))
{
if (auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
if (const auto paramCurveValuesContentChildNode = GetChildNodeByNodeName(paramCurveValuesChildNode, "values"))
{
if (paramCurveValuesContentChildNode->children)
{
@ -1149,22 +1131,22 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
else
ParseAndAssignContent(yangleChildNode, "name", "y_axis_angle", yangle);
if (auto ylengthChildNode = GetChildNode(affineChildNode, "y_axis_length"))
if (const auto ylengthChildNode = GetChildNode(affineChildNode, "y_axis_length"))
if (ParseAndAssignContent(ylengthChildNode, "name", "y_axis_length", ylength)) {}
if (auto offsetChildNode = GetChildNode(affineChildNode, "offset"))
if (const auto offsetChildNode = GetChildNode(affineChildNode, "offset"))
if (ParseAndAssignContent(offsetChildNode, "name", "offset", offsetstr))
{
istringstream istr(offsetstr);
istr >> xoffset >> yoffset;
}
T x1 = T(xlength * std::cos(xangle * DEG_2_RAD));
T y1 = T(xlength * std::sin(xangle * DEG_2_RAD));
T x2 = T(ylength * std::cos(yangle * DEG_2_RAD));
T y2 = T(ylength * std::sin(yangle * DEG_2_RAD));
T o1 = T(xoffset);
T o2 = T(yoffset);
T x1 = static_cast<T>(xlength * std::cos(xangle * DEG_2_RAD));
T y1 = static_cast<T>(xlength * std::sin(xangle * DEG_2_RAD));
T x2 = static_cast<T>(ylength * std::cos(yangle * DEG_2_RAD));
T y2 = static_cast<T>(ylength * std::sin(yangle * DEG_2_RAD));
T o1 = static_cast<T>(xoffset);
T o2 = static_cast<T>(yoffset);
xf.m_Post.A(x1);
xf.m_Post.B(x2);
xf.m_Post.C(o1);
@ -1181,38 +1163,38 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
variationsfunc(prefix, "post_transforms", transformChildNode, xf, alliterweights);
}
if (auto shaderChildNode = GetChildNodeByNodeName(node, "flam3_shader"))
if (const auto shaderChildNode = GetChildNodeByNodeName(node, "flam3_shader"))
{
T paletteIndex = 0, colorSpeed = 0.5, opacity = 1;
if (auto paletteIndexChildNode = GetChildNode(shaderChildNode, "palette_index"))
if (const auto paletteIndexChildNode = GetChildNode(shaderChildNode, "palette_index"))
if (ParseAndAssignContent(paletteIndexChildNode, "name", "palette_index", paletteIndex)) { xf.m_ColorX = xf.m_ColorY = paletteIndex; }
if (auto colrSpeedChildNode = GetChildNode(shaderChildNode, "blend_speed"))
if (const auto colrSpeedChildNode = GetChildNode(shaderChildNode, "blend_speed"))
if (ParseAndAssignContent(colrSpeedChildNode, "name", "blend_speed", colorSpeed)) { xf.m_ColorSpeed = colorSpeed; }
if (auto opacityChildNode = GetChildNode(shaderChildNode, "opacity"))
if (const auto opacityChildNode = GetChildNode(shaderChildNode, "opacity"))
if (ParseAndAssignContent(opacityChildNode, "name", "opacity", opacity)) { xf.m_Opacity = opacity; }
}
if (auto weightsChildNode = GetChildNodeByNodeName(node, "weights_selector"))
if (const auto weightsChildNode = GetChildNodeByNodeName(node, "weights_selector"))
{
T weight = 0;
std::string periterweights;
if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "base_weight"))
if (const auto baseWeightChildNode = GetChildNode(weightsChildNode, "base_weight"))
{
if (ParseAndAssignContent(baseWeightChildNode, "name", "base_weight", weight))
xf.m_Weight = weight;
}
else if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "Base weight"))
else if (const auto baseWeightChildNode = GetChildNode(weightsChildNode, "Base weight"))
{
if (ParseAndAssignContent(baseWeightChildNode, "name", "Base weight", weight))
xf.m_Weight = weight;
}
if (auto periterweightsChildNode = GetChildNode(weightsChildNode, "per_iterator_weights"))
if (const auto periterweightsChildNode = GetChildNode(weightsChildNode, "per_iterator_weights"))
{
for (auto iterweightChildNode = periterweightsChildNode->children; iterweightChildNode; iterweightChildNode = iterweightChildNode->next)
{
@ -1280,7 +1262,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
if (!bVal && !istr.bad() && !istr.fail())
currentEmber.m_HighlightPower = T(-1);
if (auto curvesnode = GetChildNodeByNodeName(childNode, "curves"))
if (const auto curvesnode = GetChildNodeByNodeName(childNode, "curves"))
{
T val = 0;
auto curvenodesfunc = [&](xmlNode * node, int index)
@ -1289,16 +1271,16 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
string knots, values;
vector<v2F> vals;
if (auto knotsnode = GetChildNode(node, "knots"))
if (const auto knotsnode = GetChildNode(node, "knots"))
{
if (auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (const auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (knotvalsnode->children)
knots = CCX(knotvalsnode->children->content);
}
if (auto valuesnode = GetChildNode(node, "values"))
if (const auto valuesnode = GetChildNode(node, "values"))
{
if (auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (const auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (valvalsnode->children)
values = CCX(valvalsnode->children->content);
}
@ -1311,11 +1293,11 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
{
if (childNode->type == XML_ELEMENT_NODE)
{
if (auto node = CheckNodeName(childNode, "table"))
if (const auto node = CheckNodeName(childNode, "table"))
{
if (!haveknots)
{
if (auto knotvalsnode = GetChildNodeByNodeName(node, "values"))
if (const auto knotvalsnode = GetChildNodeByNodeName(node, "values"))
{
if (knotvalsnode->children)
{
@ -1328,7 +1310,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
}
else if (!havevals)
{
if (auto valvalsnode = GetChildNodeByNodeName(node, "values"))
if (const auto valvalsnode = GetChildNodeByNodeName(node, "values"))
{
if (valvalsnode->children)
{
@ -1363,16 +1345,16 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
}
};
if (auto overallnode = GetChildNode(curvesnode, "overall"))
if (const auto overallnode = GetChildNode(curvesnode, "overall"))
curvenodesfunc(overallnode, 0);
if (auto rednode = GetChildNode(curvesnode, "0"))
if (const auto rednode = GetChildNode(curvesnode, "0"))
curvenodesfunc(rednode, 1);
if (auto greennode = GetChildNode(curvesnode, "5"))
if (const auto greennode = GetChildNode(curvesnode, "5"))
curvenodesfunc(greennode, 2);
if (auto bluenode = GetChildNode(curvesnode, "10"))
if (const auto bluenode = GetChildNode(curvesnode, "10"))
curvenodesfunc(bluenode, 3);
}
}
@ -1412,9 +1394,9 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
}
else if (!Compare(childNode->name, "colouring"))
{
if (auto palettenode = GetChildNode(childNode, "flam3_palette"))
if (const auto palettenode = GetChildNode(childNode, "flam3_palette"))
{
if (auto palettevalsnode = GetChildNodeByNodeName(palettenode, "values"))
if (const auto palettevalsnode = GetChildNodeByNodeName(palettenode, "values"))
{
float r = 0, g = 0, b = 0;
auto colors = CCX(palettevalsnode->children->content);
@ -1434,41 +1416,41 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
{
std::string huek, huev, satk, satv, valk, valv;
if (auto huenode = GetChildNode(childNode, "hue"))
if (const auto huenode = GetChildNode(childNode, "hue"))
{
if (auto knotsnode = GetChildNode(huenode, "knots"))
if (auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (const auto knotsnode = GetChildNode(huenode, "knots"))
if (const auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (knotvalsnode->children)
huek = CCX(knotvalsnode->children->content);
if (auto valuesnode = GetChildNode(huenode, "values"))
if (auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (const auto valuesnode = GetChildNode(huenode, "values"))
if (const auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (valvalsnode->children)
huev = CCX(valvalsnode->children->content);
}
if (auto satnode = GetChildNode(childNode, "saturation"))
if (const auto satnode = GetChildNode(childNode, "saturation"))
{
if (auto knotsnode = GetChildNode(satnode, "knots"))
if (auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (const auto knotsnode = GetChildNode(satnode, "knots"))
if (const auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (knotvalsnode->children)
satk = CCX(knotvalsnode->children->content);
if (auto valuesnode = GetChildNode(satnode, "values"))
if (auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (const auto valuesnode = GetChildNode(satnode, "values"))
if (const auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (valvalsnode->children)
satv = CCX(valvalsnode->children->content);
}
if (auto valnode = GetChildNode(childNode, "value"))
if (const auto valnode = GetChildNode(childNode, "value"))
{
if (auto knotsnode = GetChildNode(valnode, "knots"))
if (auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (const auto knotsnode = GetChildNode(valnode, "knots"))
if (const auto knotvalsnode = GetChildNodeByNodeName(knotsnode, "values"))
if (knotvalsnode->children)
valk = CCX(knotvalsnode->children->content);
if (auto valuesnode = GetChildNode(valnode, "values"))
if (auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (const auto valuesnode = GetChildNode(valnode, "values"))
if (const auto valvalsnode = GetChildNodeByNodeName(valuesnode, "values"))
if (valvalsnode->children)
valv = CCX(valvalsnode->children->content);
}
@ -1499,16 +1481,16 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
Spline<float> sspline(svec);
Spline<float> vspline(vvec);
currentEmber.m_Palette.m_Entries.resize(COLORMAP_LENGTH);
auto stepsize = (1.0f / (currentEmber.m_Palette.Size() - 1));
const auto stepsize = (1.0f / (currentEmber.m_Palette.Size() - 1));
for (auto palindex = 0; palindex < currentEmber.m_Palette.Size(); palindex++)
{
float t = palindex * stepsize;
auto h = hspline.Interpolate(t);
auto s = sspline.Interpolate(t);
auto v = vspline.Interpolate(t);
const float t = palindex * stepsize;
const auto h = hspline.Interpolate(t);
const auto s = sspline.Interpolate(t);
const auto v = vspline.Interpolate(t);
float r, g, b;
Palette<float>::HsvToRgb(float(h * 2 * M_PI), s, v, r, g, b);
Palette<float>::HsvToRgb(static_cast<float>(h * 2 * M_PI), s, v, r, g, b);
currentEmber.m_Palette.m_Entries[palindex][0] = r;
currentEmber.m_Palette.m_Entries[palindex][1] = g;
currentEmber.m_Palette.m_Entries[palindex][2] = b;
@ -1519,7 +1501,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
}
else if (!Compare(childNode->name, "node"))
{
if (auto nodename = CheckNameVal(childNode, "iterators"))
if (const auto nodename = CheckNameVal(childNode, "iterators"))
{
std::vector<std::string> alliterweights;
@ -1537,7 +1519,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
{
size_t i = 0;
while (auto xform = currentEmber.GetXform(i))
while (const auto xform = currentEmber.GetXform(i))
{
if (i < alliterweights.size() && !alliterweights[i].empty())
{
@ -1742,7 +1724,7 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
else if (!Compare(curAtt->name, "overall_curve"))
{
//cout << "found overall curves\n";
auto splits = Split(attStr, ' ');
const auto splits = Split(attStr, ' ');
istringstream is(attStr);
vector<v2F> vals;
T x = 0, y = 0;
@ -1765,7 +1747,7 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
else if (!Compare(curAtt->name, "red_curve"))
{
//cout << "found red curves\n";
auto splits = Split(attStr, ' ');
const auto splits = Split(attStr, ' ');
istringstream is(attStr);
vector<v2F> vals;
T x = 0, y = 0;
@ -1788,7 +1770,7 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
else if (!Compare(curAtt->name, "green_curve"))
{
//cout << "found green curves\n";
auto splits = Split(attStr, ' ');
const auto splits = Split(attStr, ' ');
istringstream is(attStr);
vector<v2F> vals;
T x = 0, y = 0;
@ -1811,7 +1793,7 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
else if (!Compare(curAtt->name, "blue_curve"))
{
//cout << "found blue curves\n";
auto splits = Split(attStr, ' ');
const auto splits = Split(attStr, ' ');
istringstream is(attStr);
vector<v2F> vals;
T x = 0, y = 0;
@ -1957,11 +1939,11 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
else if (!Compare(curAtt->name, "source_colors"))
{
string s(attStr);
auto vec1 = Split(s, ' ');
const auto vec1 = Split(s, ' ');
for (auto& v : vec1)
{
auto vec2 = Split(v, ',');
const auto vec2 = Split(v, ',');
if (vec2.size() == 4)
{
@ -2308,7 +2290,7 @@ bool XmlToEmber<T>::ParseXform(xmlNode* childNode, Xform<T>& xform, bool motion,
else if (!Compare(curAtt->name, "color"))
{
istringstream is(attStr);
xform.m_ColorX = xform.m_ColorY = T(0.5);
xform.m_ColorX = xform.m_ColorY = static_cast<T>(0.5);
is >> xform.m_ColorX;
is >> xform.m_ColorY;//Very unlikely to be present, but leave for future use.
}
@ -2361,7 +2343,7 @@ bool XmlToEmber<T>::ParseXform(xmlNode* childNode, Xform<T>& xform, bool motion,
//Only correct names if it came from an outside source. Names originating from this library are always considered correct.
string s = fromEmber ? string(CCX(curAtt->name)) : GetCorrectedVariationName(m_BadVariationNames, curAtt);
if (auto var = m_VariationList->GetVariation(s))
if (const auto var = m_VariationList->GetVariation(s))
{
T weight = 0;
Aton(attStr, weight);
@ -2442,7 +2424,7 @@ bool XmlToEmber<T>::ParseXform(xmlNode* childNode, Xform<T>& xform, bool motion,
//Now that all xforms have been parsed, go through and try to find params for the parametric variations.
for (size_t i = 0; i < xform.TotalVariationCount(); i++)
{
if (ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(xform.GetVariation(i)))
if (const auto parVar = dynamic_cast<ParametricVariation<T>*>(xform.GetVariation(i)))
{
for (curAtt = attPtr; curAtt; curAtt = curAtt->next)
{
@ -2600,10 +2582,10 @@ bool XmlToEmber<T>::ParseHexColors(const char* colstr, Ember<T>& ember, size_t n
while (colorCount >= ember.m_Palette.Size())
ember.m_Palette.m_Entries.push_back(v4F());
ember.m_Palette.m_Entries[colorCount][i] = float(tmp) / 255.0f;//Hex palette is [0..255], convert to [0..1].
ember.m_Palette.m_Entries[colorCount][i] = static_cast<float>(tmp) / 255.0f;//Hex palette is [0..255], convert to [0..1].
}
ember.m_Palette.m_Entries[colorCount][3] = float(1);
ember.m_Palette.m_Entries[colorCount][3] = static_cast<float>(1);
colorCount++;
}