--Code changes

-Convert all enums to class enum to be consistent with C++11 style.
 -Convert some if/else statements in filter classes to case statements.
 -Add overloaded stream operators to print various enums.
This commit is contained in:
mfeemster 2015-12-31 16:00:36 -08:00
parent 1dc363d190
commit c8e2355ec2
27 changed files with 1081 additions and 925 deletions

View File

@ -17,7 +17,7 @@ namespace EmberNs
/// Bit position specifying the presence of each type of 3D parameter. /// Bit position specifying the presence of each type of 3D parameter.
/// One, none, some or all of these can be present. /// One, none, some or all of these can be present.
/// </summary> /// </summary>
enum eProjBits enum class eProjBits : size_t
{ {
PROJBITS_ZPOS = 1, PROJBITS_ZPOS = 1,
PROJBITS_PERSP = 2, PROJBITS_PERSP = 2,
@ -214,22 +214,22 @@ public:
m_HighlightPower = -1; m_HighlightPower = -1;
m_Time = 0; m_Time = 0;
m_Background.Reset(); m_Background.Reset();
m_Interp = EMBER_INTERP_LINEAR; m_Interp = eInterp::EMBER_INTERP_LINEAR;
m_AffineInterp = AFFINE_INTERP_LOG; m_AffineInterp = eAffineInterp::AFFINE_INTERP_LOG;
//DE filter. //DE filter.
m_MinRadDE = 0; m_MinRadDE = 0;
m_MaxRadDE = 9; m_MaxRadDE = 9;
m_CurveDE = T(0.4); m_CurveDE = T(0.4);
//Spatial filter. //Spatial filter.
m_SpatialFilterType = GAUSSIAN_SPATIAL_FILTER; m_SpatialFilterType = eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER;
m_SpatialFilterRadius = T(0.5); m_SpatialFilterRadius = T(0.5);
//Temporal filter. //Temporal filter.
m_TemporalFilterType = BOX_TEMPORAL_FILTER; m_TemporalFilterType = eTemporalFilterType::BOX_TEMPORAL_FILTER;
m_TemporalFilterExp = 0; m_TemporalFilterExp = 0;
m_TemporalFilterWidth = 1; m_TemporalFilterWidth = 1;
//Palette. //Palette.
m_PaletteMode = PALETTE_LINEAR; m_PaletteMode = ePaletteMode::PALETTE_LINEAR;
m_PaletteInterp = INTERP_HSV; m_PaletteInterp = ePaletteInterp::INTERP_HSV;
//Curves. //Curves.
m_Curves.Init(); m_Curves.Init();
m_Name = "No name"; m_Name = "No name";
@ -493,16 +493,16 @@ public:
m_CamMat[1][2] = std::sin(m_CamPitch) * std::cos(-m_CamYaw); m_CamMat[1][2] = std::sin(m_CamPitch) * std::cos(-m_CamYaw);
m_CamMat[2][2] = std::cos(m_CamPitch); m_CamMat[2][2] = std::cos(m_CamPitch);
if (projBits & PROJBITS_BLUR) if (projBits & size_t(eProjBits::PROJBITS_BLUR))
{ {
if (projBits & PROJBITS_YAW) if (projBits & size_t(eProjBits::PROJBITS_YAW))
m_ProjFunc = &EmberNs::Ember<T>::ProjectPitchYawDepthBlur; m_ProjFunc = &EmberNs::Ember<T>::ProjectPitchYawDepthBlur;
else else
m_ProjFunc = &EmberNs::Ember<T>::ProjectPitchDepthBlur; m_ProjFunc = &EmberNs::Ember<T>::ProjectPitchDepthBlur;
} }
else if ((projBits & PROJBITS_PITCH) || (projBits & PROJBITS_YAW)) else if ((projBits & size_t(eProjBits::PROJBITS_PITCH)) || (projBits & size_t(eProjBits::PROJBITS_YAW)))
{ {
if (projBits & PROJBITS_YAW) if (projBits & size_t(eProjBits::PROJBITS_YAW))
m_ProjFunc = &EmberNs::Ember<T>::ProjectPitchYaw; m_ProjFunc = &EmberNs::Ember<T>::ProjectPitchYaw;
else else
m_ProjFunc = &EmberNs::Ember<T>::ProjectPitch; m_ProjFunc = &EmberNs::Ember<T>::ProjectPitch;
@ -548,9 +548,9 @@ public:
{ {
if ((onlyScaleIfNewIsSmaller && (width < m_OrigFinalRasW || height < m_OrigFinalRasH)) || !onlyScaleIfNewIsSmaller) if ((onlyScaleIfNewIsSmaller && (width < m_OrigFinalRasW || height < m_OrigFinalRasH)) || !onlyScaleIfNewIsSmaller)
{ {
if (scaleType == SCALE_WIDTH) if (scaleType == eScaleType::SCALE_WIDTH)
m_PixelsPerUnit = m_OrigPixPerUnit * (T(width) / T(m_OrigFinalRasW)); m_PixelsPerUnit = m_OrigPixPerUnit * (T(width) / T(m_OrigFinalRasW));
else if (scaleType == SCALE_HEIGHT) else if (scaleType == eScaleType::SCALE_HEIGHT)
m_PixelsPerUnit = m_OrigPixPerUnit * (T(height) / T(m_OrigFinalRasH)); m_PixelsPerUnit = m_OrigPixPerUnit * (T(height) / T(m_OrigFinalRasH));
} }
@ -717,7 +717,7 @@ public:
vector<Xform<T>*> xformVec; vector<Xform<T>*> xformVec;
//Palette and others //Palette and others
if (embers[0].m_PaletteInterp == INTERP_HSV) if (embers[0].m_PaletteInterp == ePaletteInterp::INTERP_HSV)
{ {
for (glm::length_t i = 0; i < 256; i++) for (glm::length_t i = 0; i < 256; i++)
{ {
@ -740,7 +740,7 @@ public:
Clamp<T>(m_Palette[i][j], 0, 1); Clamp<T>(m_Palette[i][j], 0, 1);
} }
} }
else if (embers[0].m_PaletteInterp == INTERP_SWEEP) else if (embers[0].m_PaletteInterp == ePaletteInterp::INTERP_SWEEP)
{ {
//Sweep - not the best option for float indices. //Sweep - not the best option for float indices.
for (glm::length_t i = 0; i < 256; i++) for (glm::length_t i = 0; i < 256; i++)
@ -888,7 +888,7 @@ public:
ClampRef<T>(thisXform->m_ColorSpeed, -1, 1); ClampRef<T>(thisXform->m_ColorSpeed, -1, 1);
//Interp affine and post. //Interp affine and post.
if (m_AffineInterp == AFFINE_INTERP_LOG) if (m_AffineInterp == eAffineInterp::AFFINE_INTERP_LOG)
{ {
vector<v2T> cxMag(size); vector<v2T> cxMag(size);
vector<v2T> cxAng(size); vector<v2T> cxAng(size);
@ -922,7 +922,7 @@ public:
Interpolater<T>::InterpAndConvertBack(coefs, cxAng, cxMag, cxTrn, thisXform->m_Post); Interpolater<T>::InterpAndConvertBack(coefs, cxAng, cxMag, cxTrn, thisXform->m_Post);
} }
} }
else if (m_AffineInterp == AFFINE_INTERP_LINEAR) else if (m_AffineInterp == eAffineInterp::AFFINE_INTERP_LINEAR)
{ {
//Interpolate pre and post affine using coefs. //Interpolate pre and post affine using coefs.
allID = true; allID = true;
@ -1033,7 +1033,7 @@ public:
continue; continue;
//Assume that if there are no variations, then it's a padding xform. //Assume that if there are no variations, then it's a padding xform.
if (m_Xforms[i].Empty() && m_AffineInterp != AFFINE_INTERP_LOG) if (m_Xforms[i].Empty() && m_AffineInterp != eAffineInterp::AFFINE_INTERP_LOG)
continue; continue;
m_Xforms[i].m_Affine.Rotate(angle); m_Xforms[i].m_Affine.Rotate(angle);
@ -1136,15 +1136,15 @@ public:
{ {
size_t val = 0; size_t val = 0;
if (m_CamZPos != 0) val |= PROJBITS_ZPOS; if (m_CamZPos != 0) val |= size_t(eProjBits::PROJBITS_ZPOS);
if (m_CamPerspective != 0) val |= PROJBITS_PERSP; if (m_CamPerspective != 0) val |= size_t(eProjBits::PROJBITS_PERSP);
if (m_CamPitch != 0) val |= PROJBITS_PITCH; if (m_CamPitch != 0) val |= size_t(eProjBits::PROJBITS_PITCH);
if (m_CamYaw != 0) val |= PROJBITS_YAW; if (m_CamYaw != 0) val |= size_t(eProjBits::PROJBITS_YAW);
if (m_CamDepthBlur != 0) val |= PROJBITS_BLUR; if (m_CamDepthBlur != 0) val |= size_t(eProjBits::PROJBITS_BLUR);
return val; return val;
} }
@ -1272,75 +1272,75 @@ public:
switch (param.first) switch (param.first)
{ {
case FLAME_MOTION_ZOOM: case eEmberMotionParam::FLAME_MOTION_ZOOM:
APP_FMP(m_Zoom); APP_FMP(m_Zoom);
break; break;
case FLAME_MOTION_ZPOS: case eEmberMotionParam::FLAME_MOTION_ZPOS:
APP_FMP(m_CamZPos); APP_FMP(m_CamZPos);
break; break;
case FLAME_MOTION_PERSPECTIVE: case eEmberMotionParam::FLAME_MOTION_PERSPECTIVE:
APP_FMP(m_CamPerspective); APP_FMP(m_CamPerspective);
break; break;
case FLAME_MOTION_YAW: case eEmberMotionParam::FLAME_MOTION_YAW:
APP_FMP(m_CamYaw); APP_FMP(m_CamYaw);
break; break;
case FLAME_MOTION_PITCH: case eEmberMotionParam::FLAME_MOTION_PITCH:
APP_FMP(m_CamPitch); APP_FMP(m_CamPitch);
break; break;
case FLAME_MOTION_DEPTH_BLUR: case eEmberMotionParam::FLAME_MOTION_DEPTH_BLUR:
APP_FMP(m_CamDepthBlur); APP_FMP(m_CamDepthBlur);
break; break;
case FLAME_MOTION_CENTER_X: case eEmberMotionParam::FLAME_MOTION_CENTER_X:
APP_FMP(m_CenterX); APP_FMP(m_CenterX);
break; break;
case FLAME_MOTION_CENTER_Y: case eEmberMotionParam::FLAME_MOTION_CENTER_Y:
APP_FMP(m_CenterY); APP_FMP(m_CenterY);
break; break;
case FLAME_MOTION_ROTATE: case eEmberMotionParam::FLAME_MOTION_ROTATE:
APP_FMP(m_Rotate); APP_FMP(m_Rotate);
break; break;
case FLAME_MOTION_BRIGHTNESS: case eEmberMotionParam::FLAME_MOTION_BRIGHTNESS:
APP_FMP(m_Brightness); APP_FMP(m_Brightness);
break; break;
case FLAME_MOTION_GAMMA: case eEmberMotionParam::FLAME_MOTION_GAMMA:
APP_FMP(m_Gamma); APP_FMP(m_Gamma);
break; break;
case FLAME_MOTION_GAMMA_THRESH: case eEmberMotionParam::FLAME_MOTION_GAMMA_THRESH:
APP_FMP(m_GammaThresh); APP_FMP(m_GammaThresh);
break; break;
case FLAME_MOTION_HIGHLIGHT_POWER: case eEmberMotionParam::FLAME_MOTION_HIGHLIGHT_POWER:
APP_FMP(m_HighlightPower); APP_FMP(m_HighlightPower);
break; break;
case FLAME_MOTION_BACKGROUND_R: case eEmberMotionParam::FLAME_MOTION_BACKGROUND_R:
APP_FMP(m_Background.r); APP_FMP(m_Background.r);
break; break;
case FLAME_MOTION_BACKGROUND_G: case eEmberMotionParam::FLAME_MOTION_BACKGROUND_G:
APP_FMP(m_Background.g); APP_FMP(m_Background.g);
break; break;
case FLAME_MOTION_BACKGROUND_B: case eEmberMotionParam::FLAME_MOTION_BACKGROUND_B:
APP_FMP(m_Background.b); APP_FMP(m_Background.b);
break; break;
case FLAME_MOTION_VIBRANCY: case eEmberMotionParam::FLAME_MOTION_VIBRANCY:
APP_FMP(m_Vibrancy); APP_FMP(m_Vibrancy);
break; break;
case FLAME_MOTION_NONE: case eEmberMotionParam::FLAME_MOTION_NONE:
default: default:
break; break;
} }
@ -1364,8 +1364,8 @@ public:
m_Symmetry = 0; m_Symmetry = 0;
m_Rotate = 0; m_Rotate = 0;
m_PixelsPerUnit = 50; m_PixelsPerUnit = 50;
m_Interp = EMBER_INTERP_LINEAR; m_Interp = eInterp::EMBER_INTERP_LINEAR;
m_PaletteInterp = INTERP_HSV; m_PaletteInterp = ePaletteInterp::INTERP_HSV;
m_Index = 0; m_Index = 0;
m_ParentFilename = ""; m_ParentFilename = "";
m_ScaleType = eScaleType::SCALE_NONE; m_ScaleType = eScaleType::SCALE_NONE;
@ -1394,12 +1394,12 @@ public:
m_CurveDE = T(0.4); m_CurveDE = T(0.4);
m_GammaThresh = T(0.01); m_GammaThresh = T(0.01);
m_TemporalSamples = 100; m_TemporalSamples = 100;
m_SpatialFilterType = GAUSSIAN_SPATIAL_FILTER; m_SpatialFilterType = eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER;
m_AffineInterp = AFFINE_INTERP_LOG; m_AffineInterp = eAffineInterp::AFFINE_INTERP_LOG;
m_TemporalFilterType = BOX_TEMPORAL_FILTER; m_TemporalFilterType = eTemporalFilterType::BOX_TEMPORAL_FILTER;
m_TemporalFilterWidth = 1; m_TemporalFilterWidth = 1;
m_TemporalFilterExp = 0; m_TemporalFilterExp = 0;
m_PaletteMode = PALETTE_STEP; m_PaletteMode = ePaletteMode::PALETTE_STEP;
} }
else else
{ {
@ -1425,12 +1425,12 @@ public:
m_CurveDE = -1; m_CurveDE = -1;
m_GammaThresh = -1; m_GammaThresh = -1;
m_TemporalSamples = 0; m_TemporalSamples = 0;
m_SpatialFilterType = GAUSSIAN_SPATIAL_FILTER; m_SpatialFilterType = eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER;
m_AffineInterp = AFFINE_INTERP_LOG; m_AffineInterp = eAffineInterp::AFFINE_INTERP_LOG;
m_TemporalFilterType = BOX_TEMPORAL_FILTER; m_TemporalFilterType = eTemporalFilterType::BOX_TEMPORAL_FILTER;
m_TemporalFilterWidth = -1; m_TemporalFilterWidth = -1;
m_TemporalFilterExp = -999; m_TemporalFilterExp = -999;
m_PaletteMode = PALETTE_STEP; m_PaletteMode = ePaletteMode::PALETTE_STEP;
} }
m_Xforms.clear(); m_Xforms.clear();

View File

@ -29,13 +29,13 @@
//Wrap the sincos function for Macs and PC. //Wrap the sincos function for Macs and PC.
#if defined(__APPLE__) || defined(_MSC_VER) #if defined(__APPLE__) || defined(_MSC_VER)
#define sincos(x, s, c) *(s)=std::sin(x); *(c)=std::cos(x); #define sincos(x, s, c) *(s)=std::sin(x); *(c)=std::cos(x);
#else #else
static void sincos(float x, float* s, float* c) static void sincos(float x, float* s, float* c)
{ {
*s = std::sin(x); *s = std::sin(x);
*c = std::cos(x); *c = std::cos(x);
} }
#endif #endif
namespace EmberNs namespace EmberNs
@ -92,9 +92,9 @@ static inline size_t NowMs()
//These two must always match. //These two must always match.
#ifdef WIN32 #ifdef WIN32
#define ALIGN __declspec(align(16)) #define ALIGN __declspec(align(16))
#else #else
#define ALIGN __attribute__ ((aligned (16))) #define ALIGN __attribute__ ((aligned (16)))
#endif #endif
#define ALIGN_CL "((aligned (16)))"//The extra parens are necessary. #define ALIGN_CL "((aligned (16)))"//The extra parens are necessary.
@ -119,35 +119,211 @@ static inline size_t NowMs()
#define m23T glm::detail::tmat2x3<T, glm::defaultp> #define m23T glm::detail::tmat2x3<T, glm::defaultp>
#endif #endif
enum eInterp : uint { EMBER_INTERP_LINEAR = 0, EMBER_INTERP_SMOOTH = 1 }; enum class eInterp : uint { EMBER_INTERP_LINEAR = 0, EMBER_INTERP_SMOOTH = 1 };
enum eAffineInterp : uint { AFFINE_INTERP_LINEAR = 0, AFFINE_INTERP_LOG = 1, AFFINE_INTERP_COMPAT = 2, AFFINE_INTERP_OLDER = 3 }; enum class eAffineInterp : uint { AFFINE_INTERP_LINEAR = 0, AFFINE_INTERP_LOG = 1, AFFINE_INTERP_COMPAT = 2, AFFINE_INTERP_OLDER = 3 };
enum ePaletteMode : uint { PALETTE_STEP = 0, PALETTE_LINEAR = 1 }; enum class ePaletteMode : uint { PALETTE_STEP = 0, PALETTE_LINEAR = 1 };
enum ePaletteInterp : uint { INTERP_HSV = 0, INTERP_SWEEP = 1 }; enum class ePaletteInterp : uint { INTERP_HSV = 0, INTERP_SWEEP = 1 };
enum eMotion : uint { MOTION_SIN = 1, MOTION_TRIANGLE = 2, MOTION_HILL = 3, MOTION_SAW = 4 }; enum class eMotion : uint { MOTION_SIN = 1, MOTION_TRIANGLE = 2, MOTION_HILL = 3, MOTION_SAW = 4 };
enum eProcessAction : uint { NOTHING = 0, ACCUM_ONLY = 1, FILTER_AND_ACCUM = 2, KEEP_ITERATING = 3, FULL_RENDER = 4 }; enum class eProcessAction : uint { NOTHING = 0, ACCUM_ONLY = 1, FILTER_AND_ACCUM = 2, KEEP_ITERATING = 3, FULL_RENDER = 4 };
enum eProcessState : uint { NONE = 0, ITER_STARTED = 1, ITER_DONE = 2, FILTER_DONE = 3, ACCUM_DONE = 4 }; enum class eProcessState : uint { NONE = 0, ITER_STARTED = 1, ITER_DONE = 2, FILTER_DONE = 3, ACCUM_DONE = 4 };
enum eInteractiveFilter : uint { FILTER_LOG = 0, FILTER_DE = 1 }; enum class eInteractiveFilter : uint { FILTER_LOG = 0, FILTER_DE = 1 };
enum eScaleType : uint { SCALE_NONE = 0, SCALE_WIDTH = 1, SCALE_HEIGHT = 2 }; enum class eScaleType : uint { SCALE_NONE = 0, SCALE_WIDTH = 1, SCALE_HEIGHT = 2 };
enum eRenderStatus : uint { RENDER_OK = 0, RENDER_ERROR = 1, RENDER_ABORT = 2 }; enum class eRenderStatus : uint { RENDER_OK = 0, RENDER_ERROR = 1, RENDER_ABORT = 2 };
enum eEmberMotionParam : uint enum class eEmberMotionParam : uint//These must remain in this order forever.
{ {
FLAME_MOTION_NONE = 0, FLAME_MOTION_NONE,
FLAME_MOTION_ZOOM = 1, FLAME_MOTION_ZOOM,
FLAME_MOTION_ZPOS = 2, FLAME_MOTION_ZPOS,
FLAME_MOTION_PERSPECTIVE = 3, FLAME_MOTION_PERSPECTIVE,
FLAME_MOTION_YAW = 4, FLAME_MOTION_YAW,
FLAME_MOTION_PITCH = 5, FLAME_MOTION_PITCH,
FLAME_MOTION_DEPTH_BLUR = 6, FLAME_MOTION_DEPTH_BLUR,
FLAME_MOTION_CENTER_X = 7, FLAME_MOTION_CENTER_X,
FLAME_MOTION_CENTER_Y = 8, FLAME_MOTION_CENTER_Y,
FLAME_MOTION_ROTATE = 9, FLAME_MOTION_ROTATE,
FLAME_MOTION_BRIGHTNESS = 10, FLAME_MOTION_BRIGHTNESS,
FLAME_MOTION_GAMMA = 11, FLAME_MOTION_GAMMA,
FLAME_MOTION_GAMMA_THRESH = 12, FLAME_MOTION_GAMMA_THRESH,
FLAME_MOTION_HIGHLIGHT_POWER = 13, FLAME_MOTION_HIGHLIGHT_POWER,
FLAME_MOTION_BACKGROUND_R = 14, FLAME_MOTION_BACKGROUND_R,
FLAME_MOTION_BACKGROUND_G = 15, FLAME_MOTION_BACKGROUND_G,
FLAME_MOTION_BACKGROUND_B = 16, FLAME_MOTION_BACKGROUND_B,
FLAME_MOTION_VIBRANCY = 17 FLAME_MOTION_VIBRANCY
}; };
/// <summary>
/// Thin wrapper to allow << operator on interp type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const eInterp& t)
{
switch (t)
{
case EmberNs::eInterp::EMBER_INTERP_LINEAR:
stream << "linear";
break;
case EmberNs::eInterp::EMBER_INTERP_SMOOTH:
stream << "smooth";
break;
default:
stream << "error";
break;
}
return stream;
}
/// <summary>
/// Thin wrapper to allow << operator on affine interp type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const eAffineInterp& t)
{
switch (t)
{
case EmberNs::eAffineInterp::AFFINE_INTERP_LINEAR:
stream << "linear";
break;
case EmberNs::eAffineInterp::AFFINE_INTERP_LOG:
stream << "log";
break;
case EmberNs::eAffineInterp::AFFINE_INTERP_COMPAT:
stream << "compat";
break;
case EmberNs::eAffineInterp::AFFINE_INTERP_OLDER:
stream << "older";
break;
default:
stream << "error";
break;
}
return stream;
}
/// <summary>
/// Thin wrapper to allow << operator on palette mode type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const ePaletteMode& t)
{
switch (t)
{
case EmberNs::ePaletteMode::PALETTE_STEP:
stream << "step";
break;
case EmberNs::ePaletteMode::PALETTE_LINEAR:
stream << "linear";
break;
default:
stream << "error";
break;
}
return stream;
}
/// <summary>
/// Thin wrapper to allow << operator on palette interp type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const ePaletteInterp& t)
{
switch (t)
{
case EmberNs::ePaletteInterp::INTERP_HSV:
stream << "hsv";
break;
case EmberNs::ePaletteInterp::INTERP_SWEEP:
stream << "sweep";
break;
default:
stream << "error";
break;
}
return stream;
}
/// <summary>
/// Thin wrapper to allow << operator on scale type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const eScaleType& t)
{
switch (t)
{
case EmberNs::eScaleType::SCALE_NONE:
stream << "none";
break;
case EmberNs::eScaleType::SCALE_WIDTH:
stream << "width";
break;
case EmberNs::eScaleType::SCALE_HEIGHT:
stream << "height";
break;
default:
stream << "error";
break;
}
return stream;
}
/// <summary>
/// Thin wrapper to allow << operator on motion type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const eMotion& t)
{
switch (t)
{
case EmberNs::eMotion::MOTION_SIN:
stream << "sin";
break;
case EmberNs::eMotion::MOTION_TRIANGLE:
stream << "triangle";
break;
case EmberNs::eMotion::MOTION_HILL:
stream << "hill";
break;
case EmberNs::eMotion::MOTION_SAW:
stream << "saw";
break;
default:
stream << "error";
break;
}
return stream;
}
} }

View File

@ -69,11 +69,10 @@ public:
/// <param name="other">The MotionParam object to copy.</param> /// <param name="other">The MotionParam object to copy.</param>
/// <returns>Reference to updated self</returns> /// <returns>Reference to updated self</returns>
template <typename U> template <typename U>
MotionParam &operator = (const MotionParam<U>& other) MotionParam& operator = (const MotionParam<U>& other)
{ {
this->first = other.first; this->first = other.first;
this->second = T(other.second); this->second = T(other.second);
return *this; return *this;
} }
}; };
@ -94,7 +93,7 @@ public:
EmberMotion() EmberMotion()
{ {
m_MotionFreq = 0; m_MotionFreq = 0;
m_MotionFunc = MOTION_SIN; m_MotionFunc = eMotion::MOTION_SIN;
m_MotionOffset = 0; m_MotionOffset = 0;
} }
@ -135,7 +134,7 @@ public:
/// <param name="other">The EmberMotion object to copy.</param> /// <param name="other">The EmberMotion object to copy.</param>
/// <returns>Reference to updated self</returns> /// <returns>Reference to updated self</returns>
template <typename U> template <typename U>
EmberMotion &operator = (const EmberMotion<U>& other) EmberMotion& operator = (const EmberMotion<U>& other)
{ {
CopyVec(m_MotionParams, other.m_MotionParams); CopyVec(m_MotionParams, other.m_MotionParams);
m_MotionFunc = other.m_MotionFunc; m_MotionFunc = other.m_MotionFunc;

View File

@ -43,7 +43,6 @@ public:
bool Save(const string& filename, Ember<T>& ember, size_t printEditDepth, bool doEdits, bool intPalette, bool hexPalette, bool append = false, bool start = false, bool finish = false) bool Save(const string& filename, Ember<T>& ember, size_t printEditDepth, bool doEdits, bool intPalette, bool hexPalette, bool append = false, bool start = false, bool finish = false)
{ {
vector<Ember<T>> vec; vector<Ember<T>> vec;
vec.push_back(ember); vec.push_back(ember);
return Save(filename, vec, printEditDepth, doEdits, intPalette, hexPalette, append, start, finish); return Save(filename, vec, printEditDepth, doEdits, intPalette, hexPalette, append, start, finish);
} }
@ -154,7 +153,6 @@ public:
string s; string s;
ostringstream os; ostringstream os;
vector<Variation<T>*> variations; vector<Variation<T>*> variations;
os << "<flame version=\"EMBER-" << EmberVersion() << "\" time=\"" << ember.m_Time << "\""; os << "<flame version=\"EMBER-" << EmberVersion() << "\" time=\"" << ember.m_Time << "\"";
if (!ember.m_Name.empty()) if (!ember.m_Name.empty())
@ -170,11 +168,10 @@ public:
os << " rotate=\"" << ember.m_Rotate << "\""; os << " rotate=\"" << ember.m_Rotate << "\"";
os << " supersample=\"" << std::max<size_t>(1, ember.m_Supersample) << "\""; os << " supersample=\"" << std::max<size_t>(1, ember.m_Supersample) << "\"";
os << " filter=\"" << ember.m_SpatialFilterRadius << "\""; os << " filter=\"" << ember.m_SpatialFilterRadius << "\"";
os << " filter_shape=\"" << ToLower(SpatialFilterCreator<T>::ToString(ember.m_SpatialFilterType)) << "\""; os << " filter_shape=\"" << ToLower(SpatialFilterCreator<T>::ToString(ember.m_SpatialFilterType)) << "\"";
os << " temporal_filter_type=\"" << ToLower(TemporalFilterCreator<T>::ToString(ember.m_TemporalFilterType)) << "\""; os << " temporal_filter_type=\"" << ToLower(TemporalFilterCreator<T>::ToString(ember.m_TemporalFilterType)) << "\"";
if (ember.m_TemporalFilterType == EXP_TEMPORAL_FILTER) if (ember.m_TemporalFilterType == eTemporalFilterType::EXP_TEMPORAL_FILTER)
os << " temporal_filter_exp=\"" << ember.m_TemporalFilterExp << "\""; os << " temporal_filter_exp=\"" << ember.m_TemporalFilterExp << "\"";
os << " temporal_filter_width=\"" << ember.m_TemporalFilterWidth << "\""; os << " temporal_filter_width=\"" << ember.m_TemporalFilterWidth << "\"";
@ -197,26 +194,26 @@ public:
os << " cam_pitch=\"" << ember.m_CamPitch << "\""; os << " cam_pitch=\"" << ember.m_CamPitch << "\"";
os << " cam_dof=\"" << ember.m_CamDepthBlur << "\""; os << " cam_dof=\"" << ember.m_CamDepthBlur << "\"";
if (ember.m_PaletteMode == PALETTE_STEP) if (ember.m_PaletteMode == ePaletteMode::PALETTE_STEP)
os << " palette_mode=\"step\""; os << " palette_mode=\"step\"";
else if (ember.m_PaletteMode == PALETTE_LINEAR) else if (ember.m_PaletteMode == ePaletteMode::PALETTE_LINEAR)
os << " palette_mode=\"linear\""; os << " palette_mode=\"linear\"";
if (ember.m_Interp == EMBER_INTERP_LINEAR) if (ember.m_Interp == eInterp::EMBER_INTERP_LINEAR)
os << " interpolation=\"linear\""; os << " interpolation=\"linear\"";
else if (ember.m_Interp == EMBER_INTERP_SMOOTH) else if (ember.m_Interp == eInterp::EMBER_INTERP_SMOOTH)
os << " interpolation=\"smooth\""; os << " interpolation=\"smooth\"";
if (ember.m_AffineInterp == AFFINE_INTERP_LINEAR) if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_LINEAR)
os << " interpolation_type=\"linear\""; os << " interpolation_type=\"linear\"";
else if (ember.m_AffineInterp == AFFINE_INTERP_LOG) else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_LOG)
os << " interpolation_type=\"log\""; os << " interpolation_type=\"log\"";
else if (ember.m_AffineInterp == AFFINE_INTERP_COMPAT) else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_COMPAT)
os << " interpolation_type=\"old\""; os << " interpolation_type=\"old\"";
else if (ember.m_AffineInterp == AFFINE_INTERP_OLDER) else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_OLDER)
os << " interpolation_type=\"older\""; os << " interpolation_type=\"older\"";
if (ember.m_PaletteInterp == INTERP_SWEEP) if (ember.m_PaletteInterp == ePaletteInterp::INTERP_SWEEP)
os << " palette_interpolation=\"sweep\""; os << " palette_interpolation=\"sweep\"";
if (!extraAttributes.empty()) if (!extraAttributes.empty())
@ -273,7 +270,6 @@ public:
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
{ {
size_t idx = 8 * i + j; size_t idx = 8 * i + j;
os << hex << setw(2) << setfill('0') << int(Rint(ember.m_Palette[idx][0] * 255)); os << hex << setw(2) << setfill('0') << int(Rint(ember.m_Palette[idx][0] * 255));
os << hex << setw(2) << setfill('0') << int(Rint(ember.m_Palette[idx][1] * 255)); os << hex << setw(2) << setfill('0') << int(Rint(ember.m_Palette[idx][1] * 255));
os << hex << setw(2) << setfill('0') << int(Rint(ember.m_Palette[idx][2] * 255)); os << hex << setw(2) << setfill('0') << int(Rint(ember.m_Palette[idx][2] * 255));
@ -292,8 +288,8 @@ public:
double g = ember.m_Palette[i][1] * 255; double g = ember.m_Palette[i][1] * 255;
double b = ember.m_Palette[i][2] * 255; double b = ember.m_Palette[i][2] * 255;
double a = ember.m_Palette[i][3] * 255; double a = ember.m_Palette[i][3] * 255;
os << " "; os << " ";
//The original used a precision of 6 which is totally unnecessary, use 2. //The original used a precision of 6 which is totally unnecessary, use 2.
if (IsClose(a, 255.0)) if (IsClose(a, 255.0))
{ {
@ -318,7 +314,6 @@ public:
os << ToString(xmlDocGetRootElement(ember.m_Edits), 1, true, printEditDepth); os << ToString(xmlDocGetRootElement(ember.m_Edits), 1, true, printEditDepth);
os << "</flame>\n"; os << "</flame>\n";
return os.str(); return os.str();
} }
@ -347,11 +342,9 @@ public:
xmlNodePtr rootNode = nullptr, node = nullptr, nodeCopy = nullptr; xmlNodePtr rootNode = nullptr, node = nullptr, nodeCopy = nullptr;
xmlNodePtr rootComment = nullptr; xmlNodePtr rootComment = nullptr;
ostringstream os; ostringstream os;
//Create the root node, called "edit". //Create the root node, called "edit".
rootNode = xmlNewNode(nullptr, XC("edit")); rootNode = xmlNewNode(nullptr, XC("edit"));
xmlDocSetRootElement(doc, rootNode); xmlDocSetRootElement(doc, rootNode);
//Add the edit attributes. //Add the edit attributes.
//Date. //Date.
myTime = time(nullptr); myTime = time(nullptr);
@ -385,13 +378,11 @@ public:
{ {
//Create a child node of the root node called sheep. //Create a child node of the root node called sheep.
node = xmlNewChild(rootNode, nullptr, XC("sheep"), nullptr); node = xmlNewChild(rootNode, nullptr, XC("sheep"), nullptr);
//Create the sheep attributes. //Create the sheep attributes.
os << sheepGen; os << sheepGen;
s = os.str(); s = os.str();
xmlNewProp(node, XC("generation"), XC(s.c_str())); xmlNewProp(node, XC("generation"), XC(s.c_str()));
os.str(""); os.str("");
os << sheepId; os << sheepId;
s = os.str(); s = os.str();
xmlNewProp(node, XC("id"), XC(s.c_str())); xmlNewProp(node, XC("id"), XC(s.c_str()));
@ -411,7 +402,6 @@ public:
node = xmlDocGetRootElement(parent0->m_Edits); node = xmlDocGetRootElement(parent0->m_Edits);
nodeCopy = xmlCopyNode(node, 1); nodeCopy = xmlCopyNode(node, 1);
AddFilenameWithoutAmpersand(nodeCopy, parent0->m_ParentFilename); AddFilenameWithoutAmpersand(nodeCopy, parent0->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str())); xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
xmlAddChild(rootNode, nodeCopy); xmlAddChild(rootNode, nodeCopy);
} }
@ -443,7 +433,7 @@ public:
else else
{ {
//Insert a (parent has no edit) message. //Insert a (parent has no edit) message.
nodeCopy = xmlNewChild(rootNode, nullptr, XC("edit"),nullptr); nodeCopy = xmlNewChild(rootNode, nullptr, XC("edit"), nullptr);
AddFilenameWithoutAmpersand(nodeCopy, parent1->m_ParentFilename); AddFilenameWithoutAmpersand(nodeCopy, parent1->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str())); xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
} }
@ -468,7 +458,6 @@ public:
//Check for errors. //Check for errors.
if (commentDoc) if (commentDoc)
{ {
//Loop through the children of the new document and copy them into the rootNode. //Loop through the children of the new document and copy them into the rootNode.
rootComment = xmlDocGetRootElement(commentDoc); rootComment = xmlDocGetRootElement(commentDoc);
@ -509,13 +498,13 @@ private:
{ {
os << " <motion motion_frequency=\"" << xform.m_MotionFreq << "\" "; os << " <motion motion_frequency=\"" << xform.m_MotionFreq << "\" ";
if (xform.m_MotionFunc == MOTION_SIN) if (xform.m_MotionFunc == eMotion::MOTION_SIN)
os << "motion_function=\"sin\" "; os << "motion_function=\"sin\" ";
else if (xform.m_MotionFunc == MOTION_TRIANGLE) else if (xform.m_MotionFunc == eMotion::MOTION_TRIANGLE)
os << "motion_function=\"triangle\" "; os << "motion_function=\"triangle\" ";
else if (xform.m_MotionFunc== MOTION_HILL) else if (xform.m_MotionFunc == eMotion::MOTION_HILL)
os << "motion_function=\"hill\" "; os << "motion_function=\"hill\" ";
else if (xform.m_MotionFunc== MOTION_SAW) else if (xform.m_MotionFunc == eMotion::MOTION_SAW)
os << "motion_function=\"saw\" "; os << "motion_function=\"saw\" ";
if (xform.m_MotionOffset != 0) if (xform.m_MotionOffset != 0)
@ -530,15 +519,17 @@ private:
} }
if (!doMotion || xform.m_ColorX != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << "\" "; if (!doMotion || xform.m_ColorX != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << "\" ";
//if (!doMotion || xform.m_ColorY != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << " " << xform.m_ColorY << "\" "; //if (!doMotion || xform.m_ColorY != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << " " << xform.m_ColorY << "\" ";
if (!doMotion || xform.m_DirectColor != EMPTYFIELD) os << "var_color=\"" << xform.m_DirectColor << "\" "; if (!doMotion || xform.m_DirectColor != EMPTYFIELD) os << "var_color=\"" << xform.m_DirectColor << "\" ";
if (!doMotion || xform.m_ColorSpeed != EMPTYFIELD) os << "color_speed=\"" << xform.m_ColorSpeed << "\" "; if (!doMotion || xform.m_ColorSpeed != EMPTYFIELD) os << "color_speed=\"" << xform.m_ColorSpeed << "\" ";
//os << "symmetry=\"" << fabs(xform.m_ColorSpeed - 1) * 2 << "\" ";//Legacy support. //os << "symmetry=\"" << fabs(xform.m_ColorSpeed - 1) * 2 << "\" ";//Legacy support.
if (!doMotion) if (!doMotion)
{ {
string s = xform.m_Name; string s = xform.m_Name;
std::replace(s.begin(), s.end(), ' ', '_'); std::replace(s.begin(), s.end(), ' ', '_');
os << "name=\"" << s << "\" ";//Flam3 didn't do this, but Apo does. os << "name=\"" << s << "\" ";//Flam3 didn't do this, but Apo does.
@ -657,8 +648,8 @@ private:
else if (!Compare(editNode->name, sheepString)) { } else if (!Compare(editNode->name, sheepString)) { }
//editOrSheep = 2; //editOrSheep = 2;
else { } else { }
//editOrSheep = 0;
//editOrSheep = 0;
//Print the attributes. //Print the attributes.
attPtr = editNode->properties; attPtr = editNode->properties;
@ -765,17 +756,20 @@ private:
switch (motion.m_MotionFunc) switch (motion.m_MotionFunc)
{ {
case MOTION_SIN: case eMotion::MOTION_SIN:
os << "\"sin\""; os << "\"sin\"";
break; break;
case MOTION_HILL:
case eMotion::MOTION_HILL:
os << "\"hill\""; os << "\"hill\"";
break; break;
case MOTION_TRIANGLE:
case eMotion::MOTION_TRIANGLE:
os << "\"triangle\""; os << "\"triangle\"";
break; break;
case eMotion::MOTION_SAW:
default: default:
case MOTION_SAW:
os << "\"saw\""; os << "\"saw\"";
break; break;
} }
@ -788,60 +782,77 @@ private:
for (size_t i = 0; i < motion.m_MotionParams.size(); ++i) for (size_t i = 0; i < motion.m_MotionParams.size(); ++i)
{ {
switch(motion.m_MotionParams[i].first) switch (motion.m_MotionParams[i].first)
{ {
case FLAME_MOTION_ZOOM: case eEmberMotionParam::FLAME_MOTION_ZOOM:
os << " zoom=\"" << motion.m_MotionParams[i].second << "\""; os << " zoom=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_ZPOS:
case eEmberMotionParam::FLAME_MOTION_ZPOS:
os << " cam_zpos=\"" << motion.m_MotionParams[i].second << "\""; os << " cam_zpos=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_PERSPECTIVE:
case eEmberMotionParam::FLAME_MOTION_PERSPECTIVE:
os << " cam_persp=\"" << motion.m_MotionParams[i].second << "\""; os << " cam_persp=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_YAW:
case eEmberMotionParam::FLAME_MOTION_YAW:
os << " cam_yaw=\"" << motion.m_MotionParams[i].second << "\""; os << " cam_yaw=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_PITCH:
case eEmberMotionParam::FLAME_MOTION_PITCH:
os << " cam_pitch=\"" << motion.m_MotionParams[i].second << "\""; os << " cam_pitch=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_DEPTH_BLUR:
case eEmberMotionParam::FLAME_MOTION_DEPTH_BLUR:
os << " cam_dof=\"" << motion.m_MotionParams[i].second << "\""; os << " cam_dof=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_CENTER_X:
case eEmberMotionParam::FLAME_MOTION_CENTER_X:
cx = motion.m_MotionParams[i].second; cx = motion.m_MotionParams[i].second;
break; break;
case FLAME_MOTION_CENTER_Y:
case eEmberMotionParam::FLAME_MOTION_CENTER_Y:
cy = motion.m_MotionParams[i].second; cy = motion.m_MotionParams[i].second;
break; break;
case FLAME_MOTION_ROTATE:
case eEmberMotionParam::FLAME_MOTION_ROTATE:
os << " rotate=\"" << motion.m_MotionParams[i].second << "\""; os << " rotate=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_BRIGHTNESS:
case eEmberMotionParam::FLAME_MOTION_BRIGHTNESS:
os << " brightness=\"" << motion.m_MotionParams[i].second << "\""; os << " brightness=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_GAMMA:
case eEmberMotionParam::FLAME_MOTION_GAMMA:
os << " gamma=\"" << motion.m_MotionParams[i].second << "\""; os << " gamma=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_GAMMA_THRESH:
case eEmberMotionParam::FLAME_MOTION_GAMMA_THRESH:
os << " gamma_threshold=\"" << motion.m_MotionParams[i].second << "\""; os << " gamma_threshold=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_HIGHLIGHT_POWER:
case eEmberMotionParam::FLAME_MOTION_HIGHLIGHT_POWER:
os << " highlight_power=\"" << motion.m_MotionParams[i].second << "\""; os << " highlight_power=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_BACKGROUND_R:
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_R:
r = motion.m_MotionParams[i].second; r = motion.m_MotionParams[i].second;
break; break;
case FLAME_MOTION_BACKGROUND_G:
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_G:
g = motion.m_MotionParams[i].second; g = motion.m_MotionParams[i].second;
break; break;
case FLAME_MOTION_BACKGROUND_B:
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_B:
b = motion.m_MotionParams[i].second; b = motion.m_MotionParams[i].second;
break; break;
case FLAME_MOTION_VIBRANCY:
case eEmberMotionParam::FLAME_MOTION_VIBRANCY:
os << " vibrancy=\"" << motion.m_MotionParams[i].second << "\""; os << " vibrancy=\"" << motion.m_MotionParams[i].second << "\"";
break; break;
case FLAME_MOTION_NONE:
case eEmberMotionParam::FLAME_MOTION_NONE:
default: default:
break; break;
} }
@ -854,7 +865,6 @@ private:
os << " center=\"" << cx << " " << cy << "\""; os << " center=\"" << cx << " " << cy << "\"";
os << "/>\n"; os << "/>\n";
return os.str(); return os.str();
} }
@ -863,7 +873,6 @@ private:
if (filename.find_first_of('&') != std::string::npos) if (filename.find_first_of('&') != std::string::npos)
{ {
string filenameWithoutAmpersands = filename; string filenameWithoutAmpersands = filename;
FindAndReplace<string>(filenameWithoutAmpersands, "&", "&amp;"); FindAndReplace<string>(filenameWithoutAmpersands, "&", "&amp;");
xmlNewProp(node, XC("filename"), XC(filenameWithoutAmpersands.c_str())); xmlNewProp(node, XC("filename"), XC(filenameWithoutAmpersands.c_str()));
} }

View File

@ -105,13 +105,12 @@ public:
if (xf >= sourceEmbers[i].TotalXformCount() && !aligned) if (xf >= sourceEmbers[i].TotalXformCount() && !aligned)
{ {
size_t found = 0; size_t found = 0;
//Remove linear. //Remove linear.
destXform->DeleteVariationById(VAR_LINEAR); destXform->DeleteVariationById(VAR_LINEAR);
//Only do the next substitution for log interpolation. //Only do the next substitution for log interpolation.
if ((i == 0 && destEmbers[i].m_AffineInterp == AFFINE_INTERP_LOG) || if ((i == 0 && destEmbers[i].m_AffineInterp == eAffineInterp::AFFINE_INTERP_LOG) ||
(i > 0 && destEmbers[i - 1].m_AffineInterp == AFFINE_INTERP_LOG)) (i > 0 && destEmbers[i - 1].m_AffineInterp == eAffineInterp::AFFINE_INTERP_LOG))
{ {
for (ii = -1; ii <= 1; ii += 2) for (ii = -1; ii <= 1; ii += 2)
{ {
@ -138,7 +137,6 @@ public:
destOtherXform->GetVariationById(VAR_WEDGE_JULIA)) destOtherXform->GetVariationById(VAR_WEDGE_JULIA))
{ {
destXform->AddVariation(new LinearVariation<T>(-1)); destXform->AddVariation(new LinearVariation<T>(-1));
//Set the coefs appropriately. //Set the coefs appropriately.
destXform->m_Affine.A(-1); destXform->m_Affine.A(-1);
destXform->m_Affine.D(0); destXform->m_Affine.D(0);
@ -168,7 +166,6 @@ public:
if (destOtherXform->GetVariationById(VAR_RECTANGLES)) if (destOtherXform->GetVariationById(VAR_RECTANGLES))
{ {
RectanglesVariation<T>* var = new RectanglesVariation<T>(); RectanglesVariation<T>* var = new RectanglesVariation<T>();
var->SetParamVal("rectangles_x", 0); var->SetParamVal("rectangles_x", 0);
var->SetParamVal("rectangles_y", 0); var->SetParamVal("rectangles_y", 0);
destXform->AddVariation(var); destXform->AddVariation(var);
@ -178,7 +175,6 @@ public:
if (destOtherXform->GetVariationById(VAR_RINGS2)) if (destOtherXform->GetVariationById(VAR_RINGS2))
{ {
Rings2Variation<T>* var = new Rings2Variation<T>(); Rings2Variation<T>* var = new Rings2Variation<T>();
var->SetParamVal("rings2_val", 0); var->SetParamVal("rings2_val", 0);
destXform->AddVariation(var); destXform->AddVariation(var);
found++; found++;
@ -187,7 +183,6 @@ public:
if (destOtherXform->GetVariationById(VAR_FAN2)) if (destOtherXform->GetVariationById(VAR_FAN2))
{ {
Fan2Variation<T>* var = new Fan2Variation<T>(); Fan2Variation<T>* var = new Fan2Variation<T>();
destXform->AddVariation(var); destXform->AddVariation(var);
found++; found++;
} }
@ -195,7 +190,6 @@ public:
if (destOtherXform->GetVariationById(VAR_BLOB)) if (destOtherXform->GetVariationById(VAR_BLOB))
{ {
BlobVariation<T>* var = new BlobVariation<T>(); BlobVariation<T>* var = new BlobVariation<T>();
var->SetParamVal("blob_low", 1); var->SetParamVal("blob_low", 1);
destXform->AddVariation(var); destXform->AddVariation(var);
found++; found++;
@ -204,7 +198,6 @@ public:
if (destOtherXform->GetVariationById(VAR_PERSPECTIVE)) if (destOtherXform->GetVariationById(VAR_PERSPECTIVE))
{ {
PerspectiveVariation<T>* var = new PerspectiveVariation<T>(); PerspectiveVariation<T>* var = new PerspectiveVariation<T>();
destXform->AddVariation(var); destXform->AddVariation(var);
found++; found++;
} }
@ -212,7 +205,6 @@ public:
if (destOtherXform->GetVariationById(VAR_CURL)) if (destOtherXform->GetVariationById(VAR_CURL))
{ {
CurlVariation<T>* var = new CurlVariation<T>(); CurlVariation<T>* var = new CurlVariation<T>();
var->SetParamVal("curl_c1", 0); var->SetParamVal("curl_c1", 0);
destXform->AddVariation(var); destXform->AddVariation(var);
found++; found++;
@ -221,7 +213,6 @@ public:
if (destOtherXform->GetVariationById(VAR_SUPER_SHAPE)) if (destOtherXform->GetVariationById(VAR_SUPER_SHAPE))
{ {
SuperShapeVariation<T>* var = new SuperShapeVariation<T>(); SuperShapeVariation<T>* var = new SuperShapeVariation<T>();
var->SetParamVal("super_shape_n1", 2); var->SetParamVal("super_shape_n1", 2);
var->SetParamVal("super_shape_n2", 2); var->SetParamVal("super_shape_n2", 2);
var->SetParamVal("super_shape_n3", 2); var->SetParamVal("super_shape_n3", 2);
@ -422,7 +413,7 @@ public:
//To interpolate the xforms, make copies of the source embers //To interpolate the xforms, make copies of the source embers
//and ensure that they both have the same number of xforms before progressing. //and ensure that they both have the same number of xforms before progressing.
if (embers[i1].m_Interp == EMBER_INTERP_LINEAR) if (embers[i1].m_Interp == eInterp::EMBER_INTERP_LINEAR)
{ {
Align(&embers[i1], &localEmbers[0], 2); Align(&embers[i1], &localEmbers[0], 2);
smoothFlag = false; smoothFlag = false;
@ -450,9 +441,9 @@ public:
} }
result.m_Time = time; result.m_Time = time;
result.m_Interp = EMBER_INTERP_LINEAR; result.m_Interp = eInterp::EMBER_INTERP_LINEAR;
result.m_AffineInterp = embers[0].m_AffineInterp; result.m_AffineInterp = embers[0].m_AffineInterp;
result.m_PaletteInterp = INTERP_HSV; result.m_PaletteInterp = ePaletteInterp::INTERP_HSV;
if (!smoothFlag) if (!smoothFlag)
result.Interpolate(&localEmbers[0], 2, c, stagger); result.Interpolate(&localEmbers[0], 2, c, stagger);
@ -668,16 +659,16 @@ public:
refang = xform->m_Wind[col] - M_2PI; refang = xform->m_Wind[col] - M_2PI;
//Make sure both angles are within [refang refang + 2 * pi]. //Make sure both angles are within [refang refang + 2 * pi].
while(cxAng[k - 1][col] < refang) while (cxAng[k - 1][col] < refang)
cxAng[k - 1][col] += M_2PI; cxAng[k - 1][col] += M_2PI;
while(cxAng[k - 1][col] > refang + M_2PI) while (cxAng[k - 1][col] > refang + M_2PI)
cxAng[k - 1][col] -= M_2PI; cxAng[k - 1][col] -= M_2PI;
while(cxAng[k][col] < refang) while (cxAng[k][col] < refang)
cxAng[k][col] += M_2PI; cxAng[k][col] += M_2PI;
while(cxAng[k][col] > refang + M_2PI) while (cxAng[k][col] > refang + M_2PI)
cxAng[k][col] -= M_2PI; cxAng[k][col] -= M_2PI;
} }
else else
@ -721,7 +712,6 @@ public:
{ {
c1[0] = embers[k].GetXform(xfi)->m_Affine.m_Mat[0][col];//A,D then B,E. c1[0] = embers[k].GetXform(xfi)->m_Affine.m_Mat[0][col];//A,D then B,E.
c1[1] = embers[k].GetXform(xfi)->m_Affine.m_Mat[1][col]; c1[1] = embers[k].GetXform(xfi)->m_Affine.m_Mat[1][col];
cxang[k][col] = atan2(c1[1], c1[0]); cxang[k][col] = atan2(c1[1], c1[0]);
} }
} }
@ -732,8 +722,7 @@ public:
{ {
int sym0, sym1; int sym0, sym1;
int padSymFlag; int padSymFlag;
d = cxang[k][col] - cxang[k - 1][col];
d = cxang[k][col] - cxang[k-1][col];
//Adjust to avoid the -pi/pi discontinuity. //Adjust to avoid the -pi/pi discontinuity.
if (d > T(M_PI + EPS)) if (d > T(M_PI + EPS))
@ -745,12 +734,11 @@ public:
//Check them pairwise and store the reference angle in the second //Check them pairwise and store the reference angle in the second
//to avoid overwriting if asymmetric on both sides. //to avoid overwriting if asymmetric on both sides.
padSymFlag = 0; padSymFlag = 0;
sym0 = (embers[k - 1].GetXform(xfi)->m_Animate == 0 || (embers[k - 1].GetXform(xfi)->Empty() && padSymFlag)); sym0 = (embers[k - 1].GetXform(xfi)->m_Animate == 0 || (embers[k - 1].GetXform(xfi)->Empty() && padSymFlag));
sym1 = (embers[k ].GetXform(xfi)->m_Animate == 0 || (embers[k ].GetXform(xfi)->Empty() && padSymFlag)); sym1 = (embers[k ].GetXform(xfi)->m_Animate == 0 || (embers[k ].GetXform(xfi)->Empty() && padSymFlag));
if (sym1 && !sym0) if (sym1 && !sym0)
embers[k].GetXform(xfi)->m_Wind[col] = cxang[k-1][col] + 2 * T(M_PI); embers[k].GetXform(xfi)->m_Wind[col] = cxang[k - 1][col] + 2 * T(M_PI);
else if (sym0 && !sym1) else if (sym0 && !sym1)
embers[k].GetXform(xfi)->m_Wind[col] = cxang[k][col] + 2 * T(M_PI); embers[k].GetXform(xfi)->m_Wind[col] = cxang[k][col] + 2 * T(M_PI);
} }
@ -835,10 +823,8 @@ public:
{ {
//maxStag is the spacing between xform start times if staggerPercent = 1.0. //maxStag is the spacing between xform start times if staggerPercent = 1.0.
T maxStag = T(numXforms - 1) / numXforms; T maxStag = T(numXforms - 1) / numXforms;
//Scale the spacing by staggerPercent. //Scale the spacing by staggerPercent.
T stagScaled = staggerPercent * maxStag; T stagScaled = staggerPercent * maxStag;
//t ranges from 1 to 0 (the contribution of cp[0] to the blend). //t ranges from 1 to 0 (the contribution of cp[0] to the blend).
//The first line below makes the first xform interpolate first. //The first line below makes the first xform interpolate first.
//The second line makes the last xform interpolate first. //The second line makes the last xform interpolate first.
@ -856,18 +842,22 @@ public:
/// <summary> /// <summary>
/// Apply the specified motion function to a value. /// Apply the specified motion function to a value.
/// </summary> /// </summary>
/// <param name="funcNum">The function type to apply, sin, triangle or hill.</param> /// <param name="funcNum">The function type to apply, sin, triangle, hill or saw.</param>
/// <param name="timeVal">The time value to apply the motion function to</param> /// <param name="timeVal">The time value to apply the motion function to</param>
/// <returns>The new time value computed by applying the specified motion function to the time value</returns> /// <returns>The new time value computed by applying the specified motion function to the time value</returns>
static T MotionFuncs(int funcNum, T timeVal) static T MotionFuncs(eMotion funcNum, T timeVal)
{ {
//Motion funcs should be cyclic, and equal to 0 at integral time values //Motion funcs should be cyclic, and equal to 0 at integral time values
//abs peak values should be not be greater than 1. //abs peak values should be not be greater than 1.
if (funcNum == MOTION_SIN) switch (funcNum)
{
case EmberNs::eMotion::MOTION_SIN:
{ {
return std::sin(T(2.0) * T(M_PI) * timeVal); return std::sin(T(2.0) * T(M_PI) * timeVal);
} }
else if (funcNum == MOTION_TRIANGLE) break;
case EmberNs::eMotion::MOTION_TRIANGLE:
{ {
T fr = fmod(timeVal, T(1.0)); T fr = fmod(timeVal, T(1.0));
@ -883,14 +873,24 @@ public:
return fr; return fr;
} }
else if (funcNum == MOTION_HILL) break;
case EmberNs::eMotion::MOTION_HILL:
{ {
return ((1 - std::cos(T(2.0) * T(M_PI) * timeVal)) * T(0.5)); return ((1 - std::cos(T(2.0) * T(M_PI) * timeVal)) * T(0.5));
} }
else //MOTION_SAW break;
case EmberNs::eMotion::MOTION_SAW:
{ {
return (T(2.0) * fmod(timeVal - T(0.5), T(1.0)) - T(1.0)); return (T(2.0) * fmod(timeVal - T(0.5), T(1.0)) - T(1.0));
} }
break;
default:
return timeVal;
break;
}
} }
/* /*
@ -1002,18 +1002,19 @@ public:
static inline bool CompareXforms(const Xform<T>& a, const Xform<T>& b) static inline bool CompareXforms(const Xform<T>& a, const Xform<T>& b)
{ {
if (a.m_ColorSpeed > b.m_ColorSpeed) return true; if (a.m_ColorSpeed > b.m_ColorSpeed) return true;
if (a.m_ColorSpeed < b.m_ColorSpeed) return false; 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. //Original did this every time, even though it's only needed if the color speeds are equal.
m2T aMat2 = a.m_Affine.ToMat2ColMajor(); m2T aMat2 = a.m_Affine.ToMat2ColMajor();
m2T bMat2 = b.m_Affine.ToMat2ColMajor(); m2T bMat2 = b.m_Affine.ToMat2ColMajor();
T ad = glm::determinant(aMat2); T ad = glm::determinant(aMat2);
T bd = glm::determinant(bMat2); T bd = glm::determinant(bMat2);
if (a.m_ColorSpeed > 0) if (a.m_ColorSpeed > 0)
{ {
if (ad < 0) return false; if (ad < 0) return false;
if (bd < 0) return true; if (bd < 0) return true;
ad = atan2(a.m_Affine.A(), a.m_Affine.D()); ad = atan2(a.m_Affine.A(), a.m_Affine.D());

View File

@ -42,7 +42,7 @@ void Renderer<T, bucketT>::AddEmber(Ember<T>& ember)
if (m_Embers.size() == 1) if (m_Embers.size() == 1)
m_Ember = m_Embers[0]; m_Ember = m_Embers[0];
}, FULL_RENDER); }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -82,7 +82,6 @@ template <typename T, typename bucketT>
void Renderer<T, bucketT>::ComputeBounds() void Renderer<T, bucketT>::ComputeBounds()
{ {
size_t maxDEFilterWidth = 0; size_t maxDEFilterWidth = 0;
m_GutterWidth = ClampGte((m_SpatialFilter->FinalFilterWidth() - Supersample()) / 2, size_t(0)); m_GutterWidth = ClampGte((m_SpatialFilter->FinalFilterWidth() - Supersample()) / 2, size_t(0));
//Check the size of the density estimation filter. //Check the size of the density estimation filter.
@ -99,7 +98,6 @@ void Renderer<T, bucketT>::ComputeBounds()
//add the DE filter width to the spatial filter width.//SMOULDER //add the DE filter width to the spatial filter width.//SMOULDER
m_DensityFilterOffset = maxDEFilterWidth; m_DensityFilterOffset = maxDEFilterWidth;
m_GutterWidth += m_DensityFilterOffset; m_GutterWidth += m_DensityFilterOffset;
m_SuperRasW = (Supersample() * FinalRasW()) + (2 * m_GutterWidth); m_SuperRasW = (Supersample() * FinalRasW()) + (2 * m_GutterWidth);
m_SuperRasH = (Supersample() * FinalRasH()) + (2 * m_GutterWidth); m_SuperRasH = (Supersample() * FinalRasH()) + (2 * m_GutterWidth);
m_SuperSize = m_SuperRasW * m_SuperRasH; m_SuperSize = m_SuperRasW * m_SuperRasH;
@ -128,22 +126,18 @@ void Renderer<T, bucketT>::ComputeCamera()
m_PixelsPerUnitX = PixelsPerUnit() * m_Scale; m_PixelsPerUnitX = PixelsPerUnit() * m_Scale;
m_PixelsPerUnitY = m_PixelsPerUnitX; m_PixelsPerUnitY = m_PixelsPerUnitX;
m_PixelsPerUnitX /= PixelAspectRatio(); m_PixelsPerUnitX /= PixelAspectRatio();
T shift = 0; T shift = 0;
T t0 = T(m_GutterWidth) / (Supersample() * m_PixelsPerUnitX); T t0 = T(m_GutterWidth) / (Supersample() * m_PixelsPerUnitX);
T t1 = T(m_GutterWidth) / (Supersample() * m_PixelsPerUnitY); T t1 = T(m_GutterWidth) / (Supersample() * m_PixelsPerUnitY);
//These go from ll to ur, moving from negative to positive. //These go from ll to ur, moving from negative to positive.
m_LowerLeftX = CenterX() - FinalRasW() / m_PixelsPerUnitX / T(2.0); m_LowerLeftX = CenterX() - FinalRasW() / m_PixelsPerUnitX / T(2.0);
m_LowerLeftY = CenterY() - FinalRasH() / m_PixelsPerUnitY / T(2.0); m_LowerLeftY = CenterY() - FinalRasH() / m_PixelsPerUnitY / T(2.0);
m_UpperRightX = m_LowerLeftX + FinalRasW() / m_PixelsPerUnitX; m_UpperRightX = m_LowerLeftX + FinalRasW() / m_PixelsPerUnitX;
m_UpperRightY = m_LowerLeftY + FinalRasH() / m_PixelsPerUnitY; m_UpperRightY = m_LowerLeftY + FinalRasH() / m_PixelsPerUnitY;
T carLlX = m_LowerLeftX - t0; T carLlX = m_LowerLeftX - t0;
T carLlY = m_LowerLeftY - t1 + shift; T carLlY = m_LowerLeftY - t1 + shift;
T carUrX = m_UpperRightX + t0; T carUrX = m_UpperRightX + t0;
T carUrY = m_UpperRightY + t1 + shift; T carUrY = m_UpperRightY + t1 + shift;
m_RotMat.MakeID(); m_RotMat.MakeID();
m_RotMat.Rotate(-Rotate()); m_RotMat.Rotate(-Rotate());
m_CarToRas.Init(carLlX, carLlY, carUrX, carUrY, m_SuperRasW, m_SuperRasH, PixelAspectRatio()); m_CarToRas.Init(carLlX, carLlY, carUrX, carUrY, m_SuperRasW, m_SuperRasH, PixelAspectRatio());
@ -157,7 +151,7 @@ void Renderer<T, bucketT>::ComputeCamera()
/// </summary> /// </summary>
/// <param name="ember">The ember to assign</param> /// <param name="ember">The ember to assign</param>
/// <param name="action">The requested process action. Note that it's critical the user supply the proper value here. /// <param name="action">The requested process action. Note that it's critical the user supply the proper value here.
/// For example: Changing dimensions without setting action to FULL_RENDER will crash the program. /// For example: Changing dimensions without setting action to eProcessAction::FULL_RENDER will crash the program.
/// However, changing only the brightness and setting action to ACCUM_ONLY is perfectly fine. /// However, changing only the brightness and setting action to ACCUM_ONLY is perfectly fine.
/// </param> /// </param>
template <typename T, typename bucketT> template <typename T, typename bucketT>
@ -186,7 +180,7 @@ void Renderer<T, bucketT>::SetEmber(vector<Ember<T>>& embers)
if (!m_Embers.empty()) if (!m_Embers.empty())
m_Ember = m_Embers[0]; m_Ember = m_Embers[0];
}, FULL_RENDER); }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -219,11 +213,12 @@ bool Renderer<T, bucketT>::CreateDEFilter(bool& newAlloc)
if (newAlloc) if (newAlloc)
{ {
if (!m_DensityFilter.get()) { return false; }//Did object creation succeed? if (!m_DensityFilter.get()) { return false; }//Did object creation succeed?
if (!m_DensityFilter->Create()) { return false; }//Object creation succeeded, did filter creation succeed? if (!m_DensityFilter->Create()) { return false; }//Object creation succeeded, did filter creation succeed?
//cout << m_DensityFilter->ToString() << endl; //cout << m_DensityFilter->ToString() << endl;
} }
else else if (!m_DensityFilter->Valid()) { return false; } //Previously created, are values ok?
if (!m_DensityFilter->Valid()) { return false; }//Previously created, are values ok?
} }
else else
{ {
@ -253,7 +248,6 @@ bool Renderer<T, bucketT>::CreateSpatialFilter(bool& newAlloc)
{ {
m_SpatialFilter = unique_ptr<SpatialFilter<bucketT>>( 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, bucketT(m_Ember.m_SpatialFilterRadius), m_Ember.m_Supersample, 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. 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; newAlloc = true;
} }
@ -332,13 +326,13 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
m_InRender = true; m_InRender = true;
EnterRender(); EnterRender();
m_Abort = false; m_Abort = false;
bool filterAndAccumOnly = m_ProcessAction == FILTER_AND_ACCUM; bool filterAndAccumOnly = m_ProcessAction == eProcessAction::FILTER_AND_ACCUM;
bool accumOnly = m_ProcessAction == ACCUM_ONLY; bool accumOnly = m_ProcessAction == eProcessAction::ACCUM_ONLY;
bool resume = m_ProcessState != NONE; bool resume = m_ProcessState != eProcessState::NONE;
bool newFilterAlloc; bool newFilterAlloc;
size_t i, temporalSample = 0; size_t i, temporalSample = 0;
T deTime; T deTime;
eRenderStatus success = RENDER_OK; auto success = eRenderStatus::RENDER_OK;
//double iterationTime = 0; //double iterationTime = 0;
//double accumulationTime = 0; //double accumulationTime = 0;
//Timing it; //Timing it;
@ -347,7 +341,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
if (!resume || accumOnly || filterAndAccumOnly) if (!resume || accumOnly || filterAndAccumOnly)
{ {
if (!resume)//Only set this if it's the first run through. if (!resume)//Only set this if it's the first run through.
m_ProcessState = ITER_STARTED; m_ProcessState = eProcessState::ITER_STARTED;
m_RenderTimer.Tic(); m_RenderTimer.Tic();
m_ProgressTimer.Tic(); m_ProgressTimer.Tic();
@ -366,7 +360,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
m_Background.Clear(); m_Background.Clear();
} }
//User requested an increase in quality after finishing. //User requested an increase in quality after finishing.
else if (m_ProcessState == ITER_STARTED && m_ProcessAction == KEEP_ITERATING && TemporalSamples() == 1) else if (m_ProcessState == eProcessState::ITER_STARTED && m_ProcessAction == eProcessAction::KEEP_ITERATING && TemporalSamples() == 1)
{ {
m_LastTemporalSample = 0; m_LastTemporalSample = 0;
m_LastIter = m_Stats.m_Iters; m_LastIter = m_Stats.m_Iters;
@ -401,6 +395,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
//Interpolate. //Interpolate.
if (m_Embers.size() > 1) if (m_Embers.size() > 1)
Interpolater<T>::Interpolate(m_Embers, T(time), 0, m_Ember); Interpolater<T>::Interpolate(m_Embers, T(time), 0, m_Ember);
//it.Toc("Interp 1"); //it.Toc("Interp 1");
//Save only for palette insertion. //Save only for palette insertion.
@ -415,14 +410,14 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
if (m_SpatialFilter.get() == nullptr || m_TemporalFilter.get() == nullptr) if (m_SpatialFilter.get() == nullptr || m_TemporalFilter.get() == nullptr)
{ {
AddToReport("Spatial and temporal filter allocations failed, aborting.\n"); AddToReport("Spatial and temporal filter allocations failed, aborting.\n");
success = RENDER_ERROR; success = eRenderStatus::RENDER_ERROR;
goto Finish; goto Finish;
} }
if (!resume && !Alloc()) if (!resume && !Alloc())
{ {
AddToReport("Histogram, accumulator and samples buffer allocations failed, aborting.\n"); AddToReport("Histogram, accumulator and samples buffer allocations failed, aborting.\n");
success = RENDER_ERROR; success = eRenderStatus::RENDER_ERROR;
goto Finish; goto Finish;
} }
@ -436,8 +431,8 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
//it.Tic(); //it.Tic();
if (m_Embers.size() > 1) if (m_Embers.size() > 1)
Interpolater<T>::Interpolate(m_Embers, deTime, 0, m_Ember); Interpolater<T>::Interpolate(m_Embers, deTime, 0, m_Ember);
//it.Toc("Interp 2");
//it.Toc("Interp 2");
ClampGteRef<T>(m_Ember.m_MinRadDE, 0); ClampGteRef<T>(m_Ember.m_MinRadDE, 0);
ClampGteRef<T>(m_Ember.m_MaxRadDE, 0); ClampGteRef<T>(m_Ember.m_MaxRadDE, 0);
ClampGteRef<T>(m_Ember.m_MaxRadDE, m_Ember.m_MinRadDE); ClampGteRef<T>(m_Ember.m_MaxRadDE, m_Ember.m_MinRadDE);
@ -445,12 +440,13 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
if (!CreateDEFilter(newFilterAlloc)) if (!CreateDEFilter(newFilterAlloc))
{ {
AddToReport("Density filter creation failed, aborting.\n"); AddToReport("Density filter creation failed, aborting.\n");
success = RENDER_ERROR; success = eRenderStatus::RENDER_ERROR;
goto Finish; goto Finish;
} }
//Temporal samples, loop 1. //Temporal samples, loop 1.
temporalSample = resume ? m_LastTemporalSample : 0; temporalSample = resume ? m_LastTemporalSample : 0;
for (; (temporalSample < TemporalSamples()) && !m_Abort;) for (; (temporalSample < TemporalSamples()) && !m_Abort;)
{ {
T colorScalar = m_TemporalFilter->Filter()[temporalSample]; T colorScalar = m_TemporalFilter->Filter()[temporalSample];
@ -466,7 +462,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
if (!resume && !AssignIterator()) if (!resume && !AssignIterator())
{ {
AddToReport("Iterator assignment failed, aborting.\n"); AddToReport("Iterator assignment failed, aborting.\n");
success = RENDER_ERROR; success = eRenderStatus::RENDER_ERROR;
goto Finish; goto Finish;
} }
@ -496,14 +492,14 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
if (stats.m_Iters == 0) if (stats.m_Iters == 0)
{ {
AddToReport("Zero iterations ran, rendering failed, aborting.\n"); AddToReport("Zero iterations ran, rendering failed, aborting.\n");
success = RENDER_ERROR; success = eRenderStatus::RENDER_ERROR;
Abort(); Abort();
goto Finish; goto Finish;
} }
if (m_Abort) if (m_Abort)
{ {
success = RENDER_ABORT; success = eRenderStatus::RENDER_ABORT;
goto Finish; goto Finish;
} }
@ -536,23 +532,23 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<byte>& finalImage, double time, s
//If we've completed all temporal samples, then it was a complete render, so report progress. //If we've completed all temporal samples, then it was a complete render, so report progress.
if (temporalSample >= TemporalSamples()) if (temporalSample >= TemporalSamples())
{ {
m_ProcessState = ITER_DONE; m_ProcessState = eProcessState::ITER_DONE;
if (m_Callback && !m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 0, 0)) if (m_Callback && !m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 0, 0))
{ {
Abort(); Abort();
success = RENDER_ABORT; success = eRenderStatus::RENDER_ABORT;
goto Finish; goto Finish;
} }
} }
FilterAndAccum: FilterAndAccum:
if (filterAndAccumOnly || temporalSample >= TemporalSamples() || forceOutput) if (filterAndAccumOnly || temporalSample >= TemporalSamples() || forceOutput)
{ {
//t.Toc("Iterating and accumulating"); //t.Toc("Iterating and accumulating");
//Compute k1 and k2. //Compute k1 and k2.
eRenderStatus fullRun = RENDER_OK;//Whether density filtering was run to completion without aborting prematurely or triggering an error. auto fullRun = eRenderStatus::RENDER_OK;//Whether density filtering was run to completion without aborting prematurely or triggering an error.
T area = FinalRasW() * FinalRasH() / (m_PixelsPerUnitX * m_PixelsPerUnitY);//Need to use temps from field if ever implemented. T area = FinalRasW() * FinalRasH() / (m_PixelsPerUnitX * m_PixelsPerUnitY);//Need to use temps from field if ever implemented.
m_K1 = bucketT((Brightness() * 268) / 256); m_K1 = bucketT((Brightness() * 268) / 256);
@ -578,18 +574,18 @@ FilterAndAccum:
else else
{ {
//Apply requested filter for a forced output during interactive rendering. //Apply requested filter for a forced output during interactive rendering.
if (m_DensityFilter.get() && m_InteractiveFilter == FILTER_DE) if (m_DensityFilter.get() && m_InteractiveFilter == eInteractiveFilter::FILTER_DE)
fullRun = GaussianDensityFilter(); fullRun = GaussianDensityFilter();
else if (!m_DensityFilter.get() || m_InteractiveFilter == FILTER_LOG) else if (!m_DensityFilter.get() || m_InteractiveFilter == eInteractiveFilter::FILTER_LOG)
fullRun = LogScaleDensityFilter(forceOutput); fullRun = LogScaleDensityFilter(forceOutput);
} }
//Only update state if iterating and filtering finished completely (didn't arrive here via forceOutput). //Only update state if iterating and filtering finished completely (didn't arrive here via forceOutput).
if (fullRun == RENDER_OK && m_ProcessState == ITER_DONE) if (fullRun == eRenderStatus::RENDER_OK && m_ProcessState == eProcessState::ITER_DONE)
m_ProcessState = FILTER_DONE; m_ProcessState = eProcessState::FILTER_DONE;
//Take special action if filtering exited prematurely. //Take special action if filtering exited prematurely.
if (fullRun != RENDER_OK) if (fullRun != eRenderStatus::RENDER_OK)
{ {
ResetBuckets(false, true);//Reset the accumulator, come back and try again on the next call. ResetBuckets(false, true);//Reset the accumulator, come back and try again on the next call.
success = fullRun; success = fullRun;
@ -598,27 +594,28 @@ FilterAndAccum:
if (m_Abort) if (m_Abort)
{ {
success = RENDER_ABORT; success = eRenderStatus::RENDER_ABORT;
goto Finish; goto Finish;
} }
//t.Toc("Density estimation filtering time: ", true); //t.Toc("Density estimation filtering time: ", true);
} }
AccumOnly: AccumOnly:
if (m_ProcessState == FILTER_DONE || forceOutput)
if (m_ProcessState == eProcessState::FILTER_DONE || forceOutput)
{ {
//Original only allowed stages 0 and 1. Add 2 to mean final accum. //Original only allowed stages 0 and 1. Add 2 to mean final accum.
//Do not update state/progress on forced output because it will be immediately overwritten. //Do not update state/progress on forced output because it will be immediately overwritten.
if (m_Callback && !forceOutput && !m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 0, 2, 0)) if (m_Callback && !forceOutput && !m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 0, 2, 0))
{ {
Abort(); Abort();
success = RENDER_ABORT; success = eRenderStatus::RENDER_ABORT;
goto Finish; goto Finish;
} }
//Make sure a filter has been created. //Make sure a filter has been created.
CreateSpatialFilter(newFilterAlloc); CreateSpatialFilter(newFilterAlloc);
m_CurvesSet = m_Ember.m_Curves.CurvesSet(); m_CurvesSet = m_Ember.m_Curves.CurvesSet();
//Color curves must be re-calculated as well. //Color curves must be re-calculated as well.
@ -626,35 +623,36 @@ AccumOnly:
for (i = 0; i < COLORMAP_LENGTH; i++) for (i = 0; i < COLORMAP_LENGTH; i++)
m_Csa[i] = m_Ember.m_Curves.BezierFunc(i / T(COLORMAP_LENGTH_MINUS_1)) * T(COLORMAP_LENGTH_MINUS_1); m_Csa[i] = m_Ember.m_Curves.BezierFunc(i / T(COLORMAP_LENGTH_MINUS_1)) * T(COLORMAP_LENGTH_MINUS_1);
if (AccumulatorToFinalImage(finalImage, finalOffset) == RENDER_OK) if (AccumulatorToFinalImage(finalImage, finalOffset) == eRenderStatus::RENDER_OK)
{ {
m_Stats.m_RenderMs = m_RenderTimer.Toc();//Record total time from the very beginning to the very end, including all intermediate calls. m_Stats.m_RenderMs = m_RenderTimer.Toc();//Record total time from the very beginning to the very end, including all intermediate calls.
//Even though the ember changes throughought the inner loops because of interpolation, it's probably ok to assign here. //Even though the ember changes throughought the inner loops because of interpolation, it's probably ok to assign here.
//This will hold the last interpolated value (even though spatial and temporal filters were created based off of one of the first interpolated values). //This will hold the last interpolated value (even though spatial and temporal filters were created based off of one of the first interpolated values).
m_LastEmber = m_Ember; m_LastEmber = m_Ember;
if (m_ProcessState == FILTER_DONE)//Only update state if gotten here legitimately, and not via forceOutput. if (m_ProcessState == eProcessState::FILTER_DONE)//Only update state if gotten here legitimately, and not via forceOutput.
{ {
m_ProcessState = ACCUM_DONE; m_ProcessState = eProcessState::ACCUM_DONE;
if (m_Callback && !m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 2, 0))//Finished. if (m_Callback && !m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 2, 0))//Finished.
{ {
Abort(); Abort();
success = RENDER_ABORT; success = eRenderStatus::RENDER_ABORT;
goto Finish; goto Finish;
} }
} }
} }
else else
{ {
success = RENDER_ERROR; success = eRenderStatus::RENDER_ERROR;
} }
} }
Finish: Finish:
if (success == RENDER_OK && m_Abort)//If everything ran ok, but they've aborted, record abort as the status.
success = RENDER_ABORT; if (success == eRenderStatus::RENDER_OK && m_Abort)//If everything ran ok, but they've aborted, record abort as the status.
else if (success != RENDER_OK)//Regardless of abort status, if there was an error, leave that as the return status. success = eRenderStatus::RENDER_ABORT;
else if (success != eRenderStatus::RENDER_OK)//Regardless of abort status, if there was an error, leave that as the return status.
Abort(); Abort();
LeaveRender(); LeaveRender();
@ -675,7 +673,6 @@ EmberImageComments Renderer<T, bucketT>::ImageComments(const EmberStats& stats,
{ {
ostringstream ss; ostringstream ss;
EmberImageComments comments; EmberImageComments comments;
ss.imbue(std::locale("")); ss.imbue(std::locale(""));
comments.m_Genome = m_EmberToXml.ToString(m_Ember, "", printEditDepth, false, intPalette, hexPalette); comments.m_Genome = m_EmberToXml.ToString(m_Ember, "", printEditDepth, false, intPalette, hexPalette);
ss << (double(stats.m_Badvals) / double(stats.m_Iters));//Percentage of bad values to iters. ss << (double(stats.m_Badvals) / double(stats.m_Iters));//Percentage of bad values to iters.
@ -684,7 +681,6 @@ EmberImageComments Renderer<T, bucketT>::ImageComments(const EmberStats& stats,
comments.m_NumIters = ss.str(); ss.str("");//Total iters. comments.m_NumIters = ss.str(); ss.str("");//Total iters.
ss << (stats.m_RenderMs / 1000.0); ss << (stats.m_RenderMs / 1000.0);
comments.m_Runtime = ss.str();//Number of seconds for iterating, accumulating and filtering. comments.m_Runtime = ss.str();//Number of seconds for iterating, accumulating and filtering.
return comments; return comments;
} }
@ -791,13 +787,14 @@ bool Renderer<T, bucketT>::ResetBuckets(bool resetHist, bool resetAccum)
//{ //{
if (resetHist && !m_HistBuckets.empty()) if (resetHist && !m_HistBuckets.empty())
Memset(m_HistBuckets); Memset(m_HistBuckets);
//}, //},
//[&] //[&]
//{ //{
if (resetAccum && !m_AccumulatorBuckets.empty()) if (resetAccum && !m_AccumulatorBuckets.empty())
Memset(m_AccumulatorBuckets); Memset(m_AccumulatorBuckets);
//});
//});
return resetHist || resetAccum; return resetHist || resetAccum;
} }
@ -820,7 +817,6 @@ void Renderer<T, bucketT>::VectorizedLogScale(size_t row, size_t rowEnd)
for (size_t i = row; i < rowEnd; i++) 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()); 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].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].g = hist[i].g * logScale;
acc[i].b = hist[i].b * logScale; acc[i].b = hist[i].b * logScale;
@ -842,7 +838,6 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
size_t endRow = m_SuperRasH; size_t endRow = m_SuperRasH;
size_t endCol = m_SuperRasW; size_t endCol = m_SuperRasW;
//Timing t(4); //Timing t(4);
//if (forceOutput)//Assume interactive render, so speed up at the expense of slight quality. //if (forceOutput)//Assume interactive render, so speed up at the expense of slight quality.
//{ //{
// parallel_for(startRow, endRow, [&](size_t j) // parallel_for(startRow, endRow, [&](size_t j)
@ -851,7 +846,6 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
// { // {
// size_t row = j * m_SuperRasW; // size_t row = j * m_SuperRasW;
// size_t rowEnd = row + endCol; // size_t rowEnd = row + endCol;
// VectorizedLogScale(row, rowEnd); // VectorizedLogScale(row, rowEnd);
// } // }
// }); // });
@ -873,7 +867,6 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
if (m_HistBuckets[i].a != 0) if (m_HistBuckets[i].a != 0)
{ {
bucketT logScale = (m_K1 * std::log(1 + m_HistBuckets[i].a * m_K2)) / m_HistBuckets[i].a; 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(). //Original did a temporary assignment, then *= logScale, then passed the result to bump_no_overflow().
//Combine here into one operation for a slight speedup. //Combine here into one operation for a slight speedup.
m_AccumulatorBuckets[i] = m_HistBuckets[i] * logScale; m_AccumulatorBuckets[i] = m_HistBuckets[i] * logScale;
@ -882,10 +875,8 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
} }
}); });
} }
//t.Toc(__FUNCTION__); //t.Toc(__FUNCTION__);
return m_Abort ? eRenderStatus::RENDER_ABORT : eRenderStatus::RENDER_OK;
return m_Abort ? RENDER_ABORT : RENDER_OK;
} }
/// <summary> /// <summary>
@ -902,14 +893,12 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
bool scf = !(Supersample() & 1); bool scf = !(Supersample() & 1);
intmax_t ss = Floor<T>(Supersample() / T(2)); intmax_t ss = Floor<T>(Supersample() / T(2));
T scfact = std::pow(Supersample() / (Supersample() + T(1)), T(2)); T scfact = std::pow(Supersample() / (Supersample() + T(1)), T(2));
size_t threads = m_ThreadsToUse; size_t threads = m_ThreadsToUse;
size_t startRow = Supersample() - 1; size_t startRow = Supersample() - 1;
size_t endRow = m_SuperRasH - (Supersample() - 1);//Original did + which is most likely wrong. size_t endRow = m_SuperRasH - (Supersample() - 1);//Original did + which is most likely wrong.
intmax_t startCol = Supersample() - 1; intmax_t startCol = Supersample() - 1;
intmax_t endCol = m_SuperRasW - (Supersample() - 1); intmax_t endCol = m_SuperRasW - (Supersample() - 1);
size_t chunkSize = size_t(ceil(double(endRow - startRow) / double(threads))); size_t chunkSize = size_t(ceil(double(endRow - startRow) / double(threads)));
//parallel_for scales very well, dividing the work almost perfectly among all processors. //parallel_for scales very well, dividing the work almost perfectly among all processors.
parallel_for(size_t(0), threads, [&] (size_t threadIndex) parallel_for(size_t(0), threads, [&] (size_t threadIndex)
{ {
@ -990,7 +979,6 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
continue; continue;
bucketT logScale = filterCoefs[filterCoefIndex] * cacheLog; bucketT logScale = filterCoefs[filterCoefIndex] * cacheLog;
//Original first assigned the fields, then scaled them. Combine into a single step for a 1% optimization. //Original first assigned the fields, then scaled them. Combine into a single step for a 1% optimization.
logScaleBucket = (*bucket * logScale); logScaleBucket = (*bucket * logScale);
@ -1053,7 +1041,7 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 1, 0); m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 1, 0);
//totalTime.Toc(__FUNCTION__); //totalTime.Toc(__FUNCTION__);
return m_Abort ? RENDER_ABORT : RENDER_OK; return m_Abort ? eRenderStatus::RENDER_ABORT : eRenderStatus::RENDER_OK;
} }
/// <summary> /// <summary>
@ -1068,7 +1056,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<byte>& pixels
if (PrepFinalAccumVector(pixels)) if (PrepFinalAccumVector(pixels))
return AccumulatorToFinalImage(pixels.data(), finalOffset); return AccumulatorToFinalImage(pixels.data(), finalOffset);
return RENDER_ERROR; return eRenderStatus::RENDER_ERROR;
} }
/// <summary> /// <summary>
@ -1082,14 +1070,13 @@ template <typename T, typename bucketT>
eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t finalOffset) eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t finalOffset)
{ {
if (!pixels) if (!pixels)
return RENDER_ERROR; return eRenderStatus::RENDER_ERROR;
EnterFinalAccum(); EnterFinalAccum();
//Timing t(4); //Timing t(4);
size_t filterWidth = m_SpatialFilter->FinalFilterWidth(); size_t filterWidth = m_SpatialFilter->FinalFilterWidth();
bucketT g, linRange, vibrancy; bucketT g, linRange, vibrancy;
Color<bucketT> background; Color<bucketT> background;
pixels += finalOffset; pixels += finalOffset;
PrepFinalAccumVals(background, g, linRange, vibrancy); PrepFinalAccumVals(background, g, linRange, vibrancy);
@ -1111,7 +1098,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t
if (m_Abort) if (m_Abort)
{ {
LeaveFinalAccum(); LeaveFinalAccum();
return RENDER_ABORT; return eRenderStatus::RENDER_ABORT;
} }
//Note that abort is not checked here. The final accumulation must run to completion //Note that abort is not checked here. The final accumulation must run to completion
@ -1142,7 +1129,6 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t
{ {
//Need to dereference the spatial filter pointer object to use the [] operator. Makes no speed difference. //Need to dereference the spatial filter pointer object to use the [] operator. Makes no speed difference.
bucketT k = ((*m_SpatialFilter)[ii + filterKRowIndex]); bucketT k = ((*m_SpatialFilter)[ii + filterKRowIndex]);
newBucket += (m_AccumulatorBuckets[(x + ii) + accumRowIndex] * k); newBucket += (m_AccumulatorBuckets[(x + ii) + accumRowIndex] * k);
} }
} }
@ -1221,17 +1207,16 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t
for (i = 0; i < FinalRasW(); i++) for (i = 0; i < FinalRasW(); i++)
{ {
byte* p = pixels + (NumChannels() * (i + j * FinalRasW())); byte* p = pixels + (NumChannels() * (i + j * FinalRasW()));
p[0] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][0] * WHITE);//The palette is [0..1], output image is [0..255]. p[0] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][0] * WHITE);//The palette is [0..1], output image is [0..255].
p[1] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][1] * WHITE); p[1] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][1] * WHITE);
p[2] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][2] * WHITE); p[2] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][2] * WHITE);
} }
} }
} }
//t.Toc(__FUNCTION__);
//t.Toc(__FUNCTION__);
LeaveFinalAccum(); LeaveFinalAccum();
return m_Abort ? RENDER_ABORT : RENDER_OK; return m_Abort ? eRenderStatus::RENDER_ABORT : eRenderStatus::RENDER_OK;
} }
//#define TG 1 //#define TG 1
@ -1270,7 +1255,8 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
for (size_t i = 0; i < m_ThreadsToUse; i++) for (size_t i = 0; i < m_ThreadsToUse; i++)
{ {
threadIndex = i; threadIndex = i;
m_TaskGroup.run([&, threadIndex] () { m_TaskGroup.run([&, threadIndex] ()
{
#else #else
parallel_for(size_t(0), m_ThreadsToUse, [&] (size_t threadIndex) parallel_for(size_t(0), m_ThreadsToUse, [&] (size_t threadIndex)
{ {
@ -1286,7 +1272,6 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
#endif #endif
//Timing t; //Timing t;
IterParams<T> params; IterParams<T> params;
m_BadVals[threadIndex] = 0; m_BadVals[threadIndex] = 0;
params.m_Count = std::min(totalItersPerThread, SubBatchSize()); params.m_Count = std::min(totalItersPerThread, SubBatchSize());
params.m_Skip = FuseCount(); params.m_Skip = FuseCount();
@ -1299,7 +1284,6 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
//Must recalculate the number of iters to run on each sub batch because the last batch will most likely have less than SubBatchSize iters. //Must recalculate the number of iters to run on each sub batch because the last batch will most likely have less than SubBatchSize iters.
//For example, if 51,000 are requested, and the sbs is 10,000, it should run 5 sub batches of 10,000 iters, and one final sub batch of 1,000 iters. //For example, if 51,000 are requested, and the sbs is 10,000, it should run 5 sub batches of 10,000 iters, and one final sub batch of 1,000 iters.
params.m_Count = std::min(params.m_Count, totalItersPerThread - m_SubBatch[threadIndex]); params.m_Count = std::min(params.m_Count, totalItersPerThread - m_SubBatch[threadIndex]);
//Use first as random point, the rest are iterated points. //Use first as random point, the rest are iterated points.
//Note that this gets reset with a new random point for each subBatchSize iterations. //Note that this gets reset with a new random point for each subBatchSize iterations.
//This helps correct if iteration happens to be on a bad trajectory. //This helps correct if iteration happens to be on a bad trajectory.
@ -1307,7 +1291,6 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
m_Samples[threadIndex][0].m_Y = m_Rand[threadIndex].template Frand11<T>(); m_Samples[threadIndex][0].m_Y = m_Rand[threadIndex].template Frand11<T>();
m_Samples[threadIndex][0].m_Z = 0;//m_Ember.m_CamZPos;//Apo set this to 0, then made the user use special variations to kick it. It seems easier to just set it to zpos. m_Samples[threadIndex][0].m_Z = 0;//m_Ember.m_CamZPos;//Apo set this to 0, then made the user use special variations to kick it. It seems easier to just set it to zpos.
m_Samples[threadIndex][0].m_ColorX = m_Rand[threadIndex].template Frand01<T>(); m_Samples[threadIndex][0].m_ColorX = m_Rand[threadIndex].template Frand01<T>();
//Finally, iterate. //Finally, iterate.
//t.Tic(); //t.Tic();
//Iterating, loop 3. //Iterating, loop 3.
@ -1317,9 +1300,11 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
if (m_LockAccum) if (m_LockAccum)
m_AccumCs.Enter(); m_AccumCs.Enter();
//t.Tic(); //t.Tic();
//Map temp buffer samples into the histogram using the palette for color. //Map temp buffer samples into the histogram using the palette for color.
Accumulate(m_Rand[threadIndex], m_Samples[threadIndex].data(), params.m_Count, &m_Dmap); Accumulate(m_Rand[threadIndex], m_Samples[threadIndex].data(), params.m_Count, &m_Dmap);
//accumulationTime += t.Toc(); //accumulationTime += t.Toc();
if (m_LockAccum) if (m_LockAccum)
m_AccumCs.Leave(); m_AccumCs.Leave();
@ -1339,7 +1324,6 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
) + temporalSample ) + temporalSample
) / double(TemporalSamples()) ) / double(TemporalSamples())
); );
double percentDiff = percent - m_LastIterPercent; double percentDiff = percent - m_LastIterPercent;
double toc = m_ProgressTimer.Toc(); double toc = m_ProgressTimer.Toc();
@ -1388,7 +1372,7 @@ template <typename T, typename bucketT> T Renderer<T, bucketT>::PixelAspectRatio
template <typename T, typename bucketT> template <typename T, typename bucketT>
void Renderer<T, bucketT>::PixelAspectRatio(T pixelAspectRatio) void Renderer<T, bucketT>::PixelAspectRatio(T pixelAspectRatio)
{ {
ChangeVal([&] { m_PixelAspectRatio = pixelAspectRatio; }, FULL_RENDER); ChangeVal([&] { m_PixelAspectRatio = pixelAspectRatio; }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -1487,7 +1471,6 @@ void Renderer<T, bucketT>::PrepFinalAccumVals(Color<bucketT>& background, bucket
g = 1 / ClampGte<bucketT>(gamma / vibGamCount, bucketT(0.01));//Ensure a divide by zero doesn't occur. g = 1 / ClampGte<bucketT>(gamma / vibGamCount, bucketT(0.01));//Ensure a divide by zero doesn't occur.
linRange = GammaThresh(); linRange = GammaThresh();
vibrancy /= vibGamCount; vibrancy /= vibGamCount;
background.x = (IsNearZero(m_Background.r) ? bucketT(m_Ember.m_Background.r) : m_Background.r) / (vibGamCount / bucketT(256.0));//Background is [0, 1]. background.x = (IsNearZero(m_Background.r) ? bucketT(m_Ember.m_Background.r) : m_Background.r) / (vibGamCount / bucketT(256.0));//Background is [0, 1].
background.y = (IsNearZero(m_Background.g) ? bucketT(m_Ember.m_Background.g) : m_Background.g) / (vibGamCount / bucketT(256.0)); background.y = (IsNearZero(m_Background.g) ? bucketT(m_Ember.m_Background.g) : m_Background.g) / (vibGamCount / bucketT(256.0));
background.z = (IsNearZero(m_Background.b) ? bucketT(m_Ember.m_Background.b) : m_Background.b) / (vibGamCount / bucketT(256.0)); background.z = (IsNearZero(m_Background.b) ? bucketT(m_Ember.m_Background.b) : m_Background.b) / (vibGamCount / bucketT(256.0));
@ -1528,7 +1511,6 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
{ {
T p00 = p.m_X - CenterX(); T p00 = p.m_X - CenterX();
T p11 = p.m_Y - m_Ember.m_RotCenterY; T p11 = p.m_Y - m_Ember.m_RotCenterY;
p.m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + CenterX(); p.m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + CenterX();
p.m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY; p.m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY;
} }
@ -1554,7 +1536,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
//Fraction = 0.7 //Fraction = 0.7
//Color = (dmap[25] * 0.3) + (dmap[26] * 0.7) //Color = (dmap[25] * 0.3) + (dmap[26] * 0.7)
//Use overloaded addition and multiplication operators in vec4 to perform the accumulation. //Use overloaded addition and multiplication operators in vec4 to perform the accumulation.
if (PaletteMode() == PALETTE_LINEAR) if (PaletteMode() == ePaletteMode::PALETTE_LINEAR)
{ {
colorIndex = bucketT(p.m_ColorX) * COLORMAP_LENGTH; colorIndex = bucketT(p.m_ColorX) * COLORMAP_LENGTH;
intColorIndex = size_t(colorIndex); intColorIndex = size_t(colorIndex);
@ -1579,7 +1561,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
else else
m_HistBuckets[histIndex] += (((dmap[intColorIndex] * (1 - colorIndexFrac)) + (dmap[intColorIndex + 1] * colorIndexFrac)) * bucketT(p.m_VizAdjusted)); m_HistBuckets[histIndex] += (((dmap[intColorIndex] * (1 - colorIndexFrac)) + (dmap[intColorIndex + 1] * colorIndexFrac)) * bucketT(p.m_VizAdjusted));
} }
else if (PaletteMode() == PALETTE_STEP) else if (PaletteMode() == ePaletteMode::PALETTE_STEP)
{ {
intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * COLORMAP_LENGTH), 0, COLORMAP_LENGTH_MINUS_1); intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * COLORMAP_LENGTH), 0, COLORMAP_LENGTH_MINUS_1);
@ -1691,7 +1673,6 @@ void Renderer<T, bucketT>::CurveAdjust(bucketT& a, const glm::length_t& index)
{ {
size_t tempIndex = size_t(Clamp<bucketT>(a, 0, COLORMAP_LENGTH_MINUS_1)); size_t tempIndex = size_t(Clamp<bucketT>(a, 0, COLORMAP_LENGTH_MINUS_1));
size_t tempIndex2 = size_t(Clamp<bucketT>(m_Csa[tempIndex].x, 0, COLORMAP_LENGTH_MINUS_1)); size_t tempIndex2 = size_t(Clamp<bucketT>(m_Csa[tempIndex].x, 0, COLORMAP_LENGTH_MINUS_1));
a = std::round(m_Csa[tempIndex2][index]); a = std::round(m_Csa[tempIndex2][index]);
} }

View File

@ -56,7 +56,7 @@ public:
virtual void ComputeBounds() override; virtual void ComputeBounds() override;
virtual void ComputeQuality() override; virtual void ComputeQuality() override;
virtual void ComputeCamera() override; virtual void ComputeCamera() override;
virtual void SetEmber(Ember<T>& ember, eProcessAction action = FULL_RENDER) override; virtual void SetEmber(Ember<T>& ember, eProcessAction action = eProcessAction::FULL_RENDER) override;
virtual void SetEmber(vector<Ember<T>>& embers) override; virtual void SetEmber(vector<Ember<T>>& embers) override;
virtual bool CreateDEFilter(bool& newAlloc) override; virtual bool CreateDEFilter(bool& newAlloc) override;
virtual bool CreateSpatialFilter(bool& newAlloc) override; virtual bool CreateSpatialFilter(bool& newAlloc) override;
@ -146,7 +146,7 @@ protected:
//Non-virtual functions that might be needed by a derived class. //Non-virtual functions that might be needed by a derived class.
void PrepFinalAccumVals(Color<bucketT>& background, bucketT& g, bucketT& linRange, bucketT& vibrancy); void PrepFinalAccumVals(Color<bucketT>& background, bucketT& g, bucketT& linRange, bucketT& vibrancy);
private: private:
//Miscellaneous non-virtual functions used only in this class. //Miscellaneous non-virtual functions used only in this class.
void Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Point<T>* samples, size_t sampleCount, const Palette<bucketT>* palette); void Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Point<T>* samples, size_t sampleCount, const Palette<bucketT>* palette);
/*inline*/ void AddToAccum(const tvec4<bucketT, glm::defaultp>& bucket, intmax_t i, intmax_t ii, intmax_t j, intmax_t jj); /*inline*/ void AddToAccum(const tvec4<bucketT, glm::defaultp>& bucket, intmax_t i, intmax_t ii, intmax_t j, intmax_t jj);

View File

@ -8,7 +8,7 @@ namespace EmberNs
/// The thread count is set to the number of cores detected on the system. /// The thread count is set to the number of cores detected on the system.
/// </summary> /// </summary>
RendererBase::RendererBase() RendererBase::RendererBase()
:m_TaskGroup(new tbb::task_group) : m_TaskGroup(new tbb::task_group)
{ {
m_Abort = false; m_Abort = false;
m_LockAccum = false; m_LockAccum = false;
@ -27,10 +27,10 @@ RendererBase::RendererBase()
m_LastTemporalSample = 0; m_LastTemporalSample = 0;
m_LastIter = 0; m_LastIter = 0;
m_LastIterPercent = 0; m_LastIterPercent = 0;
m_InteractiveFilter = FILTER_LOG; m_InteractiveFilter = eInteractiveFilter::FILTER_LOG;
m_Priority = eThreadPriority::NORMAL; m_Priority = eThreadPriority::NORMAL;
m_ProcessState = NONE; m_ProcessState = eProcessState::NONE;
m_ProcessAction = FULL_RENDER; m_ProcessAction = eProcessAction::FULL_RENDER;
m_InRender = false; m_InRender = false;
m_InFinalAccum = false; m_InFinalAccum = false;
} }
@ -56,62 +56,62 @@ void RendererBase::ChangeVal(std::function<void(void)> func, eProcessAction acti
func(); func();
//If they want a full render, don't bother inspecting process state, just start over. //If they want a full render, don't bother inspecting process state, just start over.
if (action == FULL_RENDER) if (action == eProcessAction::FULL_RENDER)
{ {
m_ProcessState = NONE; m_ProcessState = eProcessState::NONE;
m_ProcessAction = FULL_RENDER; m_ProcessAction = eProcessAction::FULL_RENDER;
} }
//Keep iterating is when rendering has completed and the user increases the quality. //Keep iterating is when rendering has completed and the user increases the quality.
//Rendering can be started where it left off by adding just the difference between the //Rendering can be started where it left off by adding just the difference between the
//new and old quality values. //new and old quality values.
else if (action == KEEP_ITERATING) else if (action == eProcessAction::KEEP_ITERATING)
{ {
if (m_ProcessState == ACCUM_DONE && TemporalSamples() == 1) if (m_ProcessState == eProcessState::ACCUM_DONE && TemporalSamples() == 1)
{ {
m_ProcessState = ITER_STARTED; m_ProcessState = eProcessState::ITER_STARTED;
m_ProcessAction = KEEP_ITERATING; m_ProcessAction = eProcessAction::KEEP_ITERATING;
} }
else//Invaid process state to handle KEEP_ITERATING, so just start over. else//Invaid process state to handle KEEP_ITERATING, so just start over.
{ {
m_ProcessState = NONE; m_ProcessState = eProcessState::NONE;
m_ProcessAction = FULL_RENDER; m_ProcessAction = eProcessAction::FULL_RENDER;
} }
} }
else if (action == FILTER_AND_ACCUM) else if (action == eProcessAction::FILTER_AND_ACCUM)
{ {
//If in the middle of a render, cannot skip to filtering or accum, so just start over. //If in the middle of a render, cannot skip to filtering or accum, so just start over.
if (m_ProcessState == NONE || m_ProcessState == ITER_STARTED) if (m_ProcessState == eProcessState::NONE || m_ProcessState == eProcessState::ITER_STARTED)
{ {
m_ProcessState = NONE; m_ProcessState = eProcessState::NONE;
m_ProcessAction = FULL_RENDER; m_ProcessAction = eProcessAction::FULL_RENDER;
} }
//Set the state to ITER_DONE and the next process action to FILTER_AND_ACCUM. //Set the state to ITER_DONE and the next process action to FILTER_AND_ACCUM.
else else
{ {
m_ProcessState = ITER_DONE; m_ProcessState = eProcessState::ITER_DONE;
m_ProcessAction = FILTER_AND_ACCUM; m_ProcessAction = eProcessAction::FILTER_AND_ACCUM;
} }
} }
//Run accum only. //Run accum only.
else if (action == ACCUM_ONLY) else if (action == eProcessAction::ACCUM_ONLY)
{ {
//Doesn't make sense if in the middle of iterating, so just start over. //Doesn't make sense if in the middle of iterating, so just start over.
if (m_ProcessState == NONE || m_ProcessState == ITER_STARTED) if (m_ProcessState == eProcessState::NONE || m_ProcessState == eProcessState::ITER_STARTED)
{ {
m_ProcessAction = FULL_RENDER; m_ProcessAction = eProcessAction::FULL_RENDER;
} }
else if (m_ProcessState == ITER_DONE)//If iterating is done, can start at density filtering and proceed. else if (m_ProcessState == eProcessState::ITER_DONE)//If iterating is done, can start at density filtering and proceed.
{ {
m_ProcessAction = FILTER_AND_ACCUM; m_ProcessAction = eProcessAction::FILTER_AND_ACCUM;
} }
else if (m_ProcessState == FILTER_DONE)//Density filtering is done, so the process action is assigned as desired. else if (m_ProcessState == eProcessState::FILTER_DONE)//Density filtering is done, so the process action is assigned as desired.
{ {
m_ProcessAction = ACCUM_ONLY; m_ProcessAction = eProcessAction::ACCUM_ONLY;
} }
else if (m_ProcessState == ACCUM_DONE)//Final accum is done, so back up and run final accum again. else if (m_ProcessState == eProcessState::ACCUM_DONE)//Final accum is done, so back up and run final accum again.
{ {
m_ProcessState = FILTER_DONE; m_ProcessState = eProcessState::FILTER_DONE;
m_ProcessAction = ACCUM_ONLY; m_ProcessAction = eProcessAction::ACCUM_ONLY;
} }
} }
@ -125,11 +125,9 @@ void RendererBase::ChangeVal(std::function<void(void)> func, eProcessAction acti
size_t RendererBase::HistMemoryRequired(size_t strips) size_t RendererBase::HistMemoryRequired(size_t strips)
{ {
bool newFilterAlloc = false; bool newFilterAlloc = false;
CreateSpatialFilter(newFilterAlloc); CreateSpatialFilter(newFilterAlloc);
CreateTemporalFilter(newFilterAlloc); CreateTemporalFilter(newFilterAlloc);
ComputeBounds(); ComputeBounds();
//Because ComputeBounds() was called, this includes gutter. //Because ComputeBounds() was called, this includes gutter.
return (SuperSize() * HistBucketSize()) / strips; return (SuperSize() * HistBucketSize()) / strips;
} }
@ -149,11 +147,9 @@ pair<size_t, size_t> RendererBase::MemoryRequired(size_t strips, bool includeFin
{ {
pair<size_t, size_t> p; pair<size_t, size_t> p;
size_t outSize = includeFinal ? FinalBufferSize() : 0; size_t outSize = includeFinal ? FinalBufferSize() : 0;
outSize *= (threadedWrite ? 2 : 1); outSize *= (threadedWrite ? 2 : 1);
p.first = HistMemoryRequired(strips); p.first = HistMemoryRequired(strips);
p.second = (p.first * 2) + outSize;//Multiply hist by 2 to account for the density filtering buffer which is the same size as the histogram. p.second = (p.first * 2) + outSize;//Multiply hist by 2 to account for the density filtering buffer which is the same size as the histogram.
return p; return p;
} }
@ -183,7 +179,7 @@ bool RendererBase::RandVec(vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>>& randVec)
{ {
m_Rand = randVec; m_Rand = randVec;
b = true; b = true;
}, FULL_RENDER); }, eProcessAction::FULL_RENDER);
} }
return b; return b;
@ -218,7 +214,6 @@ bool RendererBase::PrepFinalAccumVector(vector<byte>& pixels)
} }
LeaveResize(); LeaveResize();
return pixels.size() >= size;//Ensure allocation went ok. return pixels.size() >= size;//Ensure allocation went ok.
} }
@ -244,21 +239,14 @@ bool RendererBase::Ok() const
size_t RendererBase::MemoryAvailable() size_t RendererBase::MemoryAvailable()
{ {
size_t memAvailable = 0; size_t memAvailable = 0;
#ifdef WIN32 #ifdef WIN32
MEMORYSTATUSEX stat; MEMORYSTATUSEX stat;
stat.dwLength = sizeof(stat); stat.dwLength = sizeof(stat);
GlobalMemoryStatusEx(&stat); GlobalMemoryStatusEx(&stat);
memAvailable = stat.ullTotalPhys; memAvailable = stat.ullTotalPhys;
#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
memAvailable = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); memAvailable = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
#elif defined __APPLE__ #elif defined __APPLE__
#ifdef __LP64__ #ifdef __LP64__
long physmem; long physmem;
size_t len = sizeof(physmem); size_t len = sizeof(physmem);
@ -280,12 +268,9 @@ size_t RendererBase::MemoryAvailable()
} }
#else #else
cout << "Warning: unable to determine physical memory." << endl; cout << "Warning: unable to determine physical memory." << endl;
memAvailable = 4e9; memAvailable = 4e9;
#endif #endif
return memAvailable; return memAvailable;
} }
@ -336,7 +321,7 @@ bool RendererBase::LockAccum() const { return m_LockAccum; }
/// <param name="lockAccum">True if the histogram should be locked when accumulating, else false</param> /// <param name="lockAccum">True if the histogram should be locked when accumulating, else false</param>
void RendererBase::LockAccum(bool lockAccum) void RendererBase::LockAccum(bool lockAccum)
{ {
ChangeVal([&] { m_LockAccum = lockAccum; }, FULL_RENDER); ChangeVal([&] { m_LockAccum = lockAccum; }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -355,7 +340,7 @@ bool RendererBase::EarlyClip() const { return m_EarlyClip; }
/// <param name="earlyClip">True if early clip, else false.</param> /// <param name="earlyClip">True if early clip, else false.</param>
void RendererBase::EarlyClip(bool earlyClip) void RendererBase::EarlyClip(bool earlyClip)
{ {
ChangeVal([&] { m_EarlyClip = earlyClip; }, FILTER_AND_ACCUM); ChangeVal([&] { m_EarlyClip = earlyClip; }, eProcessAction::FILTER_AND_ACCUM);
} }
/// <summary> /// <summary>
@ -371,7 +356,7 @@ bool RendererBase::YAxisUp() const { return m_YAxisUp; }
/// <param name="yup">True if the positive y axis is up, else false.</param> /// <param name="yup">True if the positive y axis is up, else false.</param>
void RendererBase::YAxisUp(bool yup) void RendererBase::YAxisUp(bool yup)
{ {
ChangeVal([&] { m_YAxisUp = yup; }, ACCUM_ONLY); ChangeVal([&] { m_YAxisUp = yup; }, eProcessAction::ACCUM_ONLY);
} }
/// <summary> /// <summary>
@ -390,7 +375,7 @@ bool RendererBase::InsertPalette() const { return m_InsertPalette; }
/// <param name="insertPalette">True if inserting the palette, else false.</param> /// <param name="insertPalette">True if inserting the palette, else false.</param>
void RendererBase::InsertPalette(bool insertPalette) void RendererBase::InsertPalette(bool insertPalette)
{ {
ChangeVal([&] { m_InsertPalette = insertPalette; }, ACCUM_ONLY); ChangeVal([&] { m_InsertPalette = insertPalette; }, eProcessAction::ACCUM_ONLY);
} }
/// <summary> /// <summary>
@ -409,7 +394,7 @@ bool RendererBase::ReclaimOnResize() const { return m_ReclaimOnResize; }
/// <param name="reclaimOnResize">True if reclaim, else false.</param> /// <param name="reclaimOnResize">True if reclaim, else false.</param>
void RendererBase::ReclaimOnResize(bool reclaimOnResize) void RendererBase::ReclaimOnResize(bool reclaimOnResize)
{ {
ChangeVal([&] { m_ReclaimOnResize = reclaimOnResize; }, FULL_RENDER); ChangeVal([&] { m_ReclaimOnResize = reclaimOnResize; }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -430,7 +415,7 @@ bool RendererBase::Transparency() const { return m_Transparency; }
/// <param name="transparency">True if using transparency, else false.</param> /// <param name="transparency">True if using transparency, else false.</param>
void RendererBase::Transparency(bool transparency) void RendererBase::Transparency(bool transparency)
{ {
ChangeVal([&] { m_Transparency = transparency; }, ACCUM_ONLY); ChangeVal([&] { m_Transparency = transparency; }, eProcessAction::ACCUM_ONLY);
} }
/// <summary> /// <summary>
@ -483,7 +468,6 @@ void RendererBase::ThreadCount(size_t threads, const char* seedString)
if (seedString) if (seedString)
{ {
ISAAC_INT newSize = ISAAC_INT(size + 5 + (t.Toc() + t.EndTime())); ISAAC_INT newSize = ISAAC_INT(size + 5 + (t.Toc() + t.EndTime()));
#ifdef ISAAC_FLAM3_DEBUG #ifdef ISAAC_FLAM3_DEBUG
QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(0, 0, 0, seeds); QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(0, 0, 0, seeds);
#else #else
@ -505,11 +489,10 @@ void RendererBase::ThreadCount(size_t threads, const char* seedString)
t.Toc(); t.Toc();
ISAAC_INT r = ISAAC_INT((size * i) + i + t.EndTime()); ISAAC_INT r = ISAAC_INT((size * i) + i + t.EndTime());
QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(r, r * 2, r * 3, seeds); QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(r, r * 2, r * 3, seeds);
m_Rand.push_back(isaac); m_Rand.push_back(isaac);
} }
} }
}, FULL_RENDER); }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -536,7 +519,7 @@ void RendererBase::BytesPerChannel(size_t bytesPerChannel)
m_BytesPerChannel = 1; m_BytesPerChannel = 1;
else else
m_BytesPerChannel = bytesPerChannel; m_BytesPerChannel = bytesPerChannel;
}, ACCUM_ONLY); }, eProcessAction::ACCUM_ONLY);
} }
/// <summary> /// <summary>
@ -576,7 +559,7 @@ eInteractiveFilter RendererBase::InteractiveFilter() const { return m_Interactiv
/// <param name="filter">The filter.</param> /// <param name="filter">The filter.</param>
void RendererBase::InteractiveFilter(eInteractiveFilter filter) void RendererBase::InteractiveFilter(eInteractiveFilter filter)
{ {
ChangeVal([&] { m_InteractiveFilter = filter; }, FULL_RENDER); ChangeVal([&] { m_InteractiveFilter = filter; }, eProcessAction::FULL_RENDER);
} }
/// <summary> /// <summary>
@ -592,7 +575,7 @@ void RendererBase::InteractiveFilter(eInteractiveFilter filter)
/// <param name="numChannels">The number of channels per pixel in the output image</param> /// <param name="numChannels">The number of channels per pixel in the output image</param>
void RendererBase::NumChannels(size_t numChannels) void RendererBase::NumChannels(size_t numChannels)
{ {
ChangeVal([&] { m_NumChannels = numChannels; }, ACCUM_ONLY); ChangeVal([&] { m_NumChannels = numChannels; }, eProcessAction::ACCUM_ONLY);
} }
/// <summary> /// <summary>
@ -623,8 +606,8 @@ void RendererBase::Reset()
EnterFinalAccum(); EnterFinalAccum();
LeaveFinalAccum(); LeaveFinalAccum();
LeaveRender(); LeaveRender();
m_ProcessState = NONE; m_ProcessState = eProcessState::NONE;
m_ProcessAction = FULL_RENDER; m_ProcessAction = eProcessAction::FULL_RENDER;
} }
void RendererBase::EnterRender() { m_RenderingCs.Enter(); } void RendererBase::EnterRender() { m_RenderingCs.Enter(); }

View File

@ -106,9 +106,9 @@ public:
//Virtual processing functions. //Virtual processing functions.
virtual bool Ok() const; virtual bool Ok() const;
virtual size_t MemoryAvailable(); virtual size_t MemoryAvailable();
virtual void SetEmber(Ember<float>& ember, eProcessAction action = FULL_RENDER) { } virtual void SetEmber(Ember<float>& ember, eProcessAction action = eProcessAction::FULL_RENDER) { }
virtual void SetEmber(vector<Ember<float>>& embers) { } virtual void SetEmber(vector<Ember<float>>& embers) { }
virtual void SetEmber(Ember<double>& ember, eProcessAction action = FULL_RENDER) { } virtual void SetEmber(Ember<double>& ember, eProcessAction action = eProcessAction::FULL_RENDER) { }
virtual void SetEmber(vector<Ember<double>>& embers) { } virtual void SetEmber(vector<Ember<double>>& embers) { }
virtual bool RandVec(vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>>& randVec); virtual bool RandVec(vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>>& randVec);

View File

@ -64,14 +64,12 @@ public:
SheepTools(const string& palettePath, Renderer<T, bucketT>* renderer) SheepTools(const string& palettePath, Renderer<T, bucketT>* renderer)
{ {
Timing t; Timing t;
m_Smooth = true; m_Smooth = true;
m_SheepGen = -1; m_SheepGen = -1;
m_SheepId = -1; m_SheepId = -1;
m_Stagger = 0; m_Stagger = 0;
m_OffsetX = 0; m_OffsetX = 0;
m_OffsetY = 0; m_OffsetY = 0;
m_PaletteList.Add(palettePath); m_PaletteList.Add(palettePath);
m_StandardIterator = unique_ptr<StandardIterator<T>>(new StandardIterator<T>()); m_StandardIterator = unique_ptr<StandardIterator<T>>(new StandardIterator<T>());
m_XaosIterator = unique_ptr<XaosIterator<T>>(new XaosIterator<T>()); m_XaosIterator = unique_ptr<XaosIterator<T>>(new XaosIterator<T>());
@ -86,15 +84,12 @@ public:
Ember<T> CreateLinearDefault() Ember<T> CreateLinearDefault()
{ {
Ember<T> ember; Ember<T> ember;
Xform<T> xform1(T(0.25), T(1), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.5), T(0.25)); Xform<T> xform1(T(0.25), T(1), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.5), T(0.25));
Xform<T> xform2(T(0.25), T(0.66), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(-0.5), T(0.25)); Xform<T> xform2(T(0.25), T(0.66), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(-0.5), T(0.25));
Xform<T> xform3(T(0.25), T(0.33), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.0), T(-0.5)); Xform<T> xform3(T(0.25), T(0.33), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.0), T(-0.5));
xform1.AddVariation(new LinearVariation<T>()); xform1.AddVariation(new LinearVariation<T>());
xform2.AddVariation(new LinearVariation<T>()); xform2.AddVariation(new LinearVariation<T>());
xform3.AddVariation(new LinearVariation<T>()); xform3.AddVariation(new LinearVariation<T>());
ember.AddXform(xform1); ember.AddXform(xform1);
ember.AddXform(xform2); ember.AddXform(xform2);
ember.AddXform(xform3); ember.AddXform(xform3);
@ -142,7 +137,6 @@ public:
{ {
Variation<T>* var = nullptr; Variation<T>* var = nullptr;
Variation<T>* smallestVar = nullptr; Variation<T>* smallestVar = nullptr;
numVars = 0; numVars = 0;
smallest = -1; smallest = -1;
@ -171,7 +165,8 @@ public:
if (smallestVar) if (smallestVar)
xform->DeleteVariationById(smallestVar->VariationId()); xform->DeleteVariationById(smallestVar->VariationId());
} }
} while (numVars > maxVars); }
while (numVars > maxVars);
} }
return os.str(); return os.str();
@ -194,7 +189,6 @@ public:
T randSelect; T randSelect;
ostringstream os; ostringstream os;
Ember<T> mutation; Ember<T> mutation;
mutation.Clear(); mutation.Clear();
//If mutate_mode = -1, choose a random mutation mode. //If mutate_mode = -1, choose a random mutation mode.
@ -251,13 +245,13 @@ public:
} }
} }
} }
} while (!done); }
while (!done);
} }
else if (mode == MUTATE_ONE_XFORM_COEFS) else if (mode == MUTATE_ONE_XFORM_COEFS)
{ {
//Generate a 2-xform random. //Generate a 2-xform random.
Random(mutation, useVars, sym, 2, maxVars); Random(mutation, useVars, sym, 2, maxVars);
//Which xform to mutate? //Which xform to mutate?
modXform = m_Rand.Rand() % ember.TotalXformCount(); modXform = m_Rand.Rand() % ember.TotalXformCount();
Xform<T>* xform1 = ember.GetTotalXform(modXform); Xform<T>* xform1 = ember.GetTotalXform(modXform);
@ -286,7 +280,6 @@ public:
{ {
bool same = (m_Rand.Rand() & 3) > 0;//25% chance of using the same post for all of them. bool 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; size_t b = 1 + m_Rand.Rand() % 6;
os << "mutate post xforms " << b << (same ? " same" : ""); os << "mutate post xforms " << b << (same ? " same" : "");
for (size_t i = 0; i < ember.TotalXformCount(); i++) for (size_t i = 0; i < ember.TotalXformCount(); i++)
@ -305,24 +298,19 @@ public:
{ {
T f = T(M_PI) * m_Rand.Frand11<T>(); T f = T(M_PI) * m_Rand.Frand11<T>();
T ra, rb, rd, re; T ra, rb, rd, re;
ra = (xform->m_Affine.A() * std::cos(f) + xform->m_Affine.B() * -std::sin(f)); 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)); rd = (xform->m_Affine.A() * std::sin(f) + xform->m_Affine.D() * std::cos(f));
rb = (xform->m_Affine.B() * std::cos(f) + xform->m_Affine.E() * -std::sin(f)); rb = (xform->m_Affine.B() * std::cos(f) + xform->m_Affine.E() * -std::sin(f));
re = (xform->m_Affine.B() * std::sin(f) + xform->m_Affine.E() * std::cos(f)); re = (xform->m_Affine.B() * std::sin(f) + xform->m_Affine.E() * std::cos(f));
xform->m_Affine.A(ra); xform->m_Affine.A(ra);
xform->m_Affine.B(rb); xform->m_Affine.B(rb);
xform->m_Affine.D(rd); xform->m_Affine.D(rd);
xform->m_Affine.E(re); xform->m_Affine.E(re);
f *= -1; f *= -1;
ra = (xform->m_Post.A() * std::cos(f) + xform->m_Post.B() * -std::sin(f)); ra = (xform->m_Post.A() * std::cos(f) + xform->m_Post.B() * -std::sin(f));
rd = (xform->m_Post.A() * std::sin(f) + xform->m_Post.D() * std::cos(f)); rd = (xform->m_Post.A() * std::sin(f) + xform->m_Post.D() * std::cos(f));
rb = (xform->m_Post.B() * std::cos(f) + xform->m_Post.E() * -std::sin(f)); rb = (xform->m_Post.B() * std::cos(f) + xform->m_Post.E() * -std::sin(f));
re = (xform->m_Post.B() * std::sin(f) + xform->m_Post.E() * std::cos(f)); re = (xform->m_Post.B() * std::sin(f) + xform->m_Post.E() * std::cos(f));
xform->m_Post.A(ra); xform->m_Post.A(ra);
xform->m_Post.B(rb); xform->m_Post.B(rb);
xform->m_Post.D(rd); xform->m_Post.D(rd);
@ -340,8 +328,7 @@ public:
if (m_Rand.RandBit()) if (m_Rand.RandBit())
g = f; g = f;
else else if (m_Rand.RandBit())
if (m_Rand.RandBit())
g = 1 / g; g = 1 / g;
xform->m_Affine.A(xform->m_Affine.A() / f); xform->m_Affine.A(xform->m_Affine.A() / f);
@ -358,7 +345,6 @@ public:
{ {
T f = m_Rand.Frand11<T>(); T f = m_Rand.Frand11<T>();
T g = m_Rand.Frand11<T>(); T g = m_Rand.Frand11<T>();
xform->m_Affine.C(xform->m_Affine.C() - f); xform->m_Affine.C(xform->m_Affine.C() - f);
xform->m_Affine.F(xform->m_Affine.F() - g); xform->m_Affine.F(xform->m_Affine.F() - g);
xform->m_Post.C(xform->m_Post.C() + f); xform->m_Post.C(xform->m_Post.C() + f);
@ -473,7 +459,6 @@ public:
Ember<T> parents[2]; Ember<T> parents[2];
//t = 0.5;//If you ever need to test. //t = 0.5;//If you ever need to test.
t = m_Rand.Frand01<T>(); t = m_Rand.Frand01<T>();
parents[0] = ember0; parents[0] = ember0;
parents[1] = ember1; parents[1] = ember1;
parents[0].m_Time = T(0); parents[0].m_Time = T(0);
@ -497,7 +482,6 @@ public:
got0 = got1 = 0; got0 = got1 = 0;
rb = m_Rand.RandBit(); rb = m_Rand.RandBit();
os << rb << ":"; os << rb << ":";
//Copy the parent, sorting the final xform to the end if it's present. //Copy the parent, sorting the final xform to the end if it's present.
emberOut = rb ? ember1 : ember0; emberOut = rb ? ember1 : ember0;
usedParent = rb; usedParent = rb;
@ -556,8 +540,8 @@ public:
got0 = 1; got0 = 1;
else if (usedParent == 1 && ember1.UseFinalXform()) else if (usedParent == 1 && ember1.UseFinalXform())
got1 = 1; got1 = 1;
}
} while ((i > 1) && !(got0 && got1)); while ((i > 1) && !(got0 && got1));
os << "cross alternate "; os << "cross alternate ";
os << trystr; os << trystr;
@ -577,7 +561,6 @@ public:
//Select the starting parent. //Select the starting parent.
size_t ci; size_t ci;
uint startParent = m_Rand.RandBit(); uint startParent = m_Rand.RandBit();
os << " cmap_cross " << startParent << ":"; os << " cmap_cross " << startParent << ":";
//Loop over the entries, switching to the other parent 1% of the time. //Loop over the entries, switching to the other parent 1% of the time.
@ -604,7 +587,6 @@ public:
void Random(Ember<T>& ember, size_t maxVars) void Random(Ember<T>& ember, size_t maxVars)
{ {
vector<eVariationId> useVars; vector<eVariationId> useVars;
Random(ember, useVars, static_cast<intmax_t>(m_Rand.Frand<T>(-2, 2)), 0, maxVars); Random(ember, useVars, static_cast<intmax_t>(m_Rand.Frand<T>(-2, 2)), 0, maxVars);
} }
@ -623,7 +605,6 @@ public:
glm::length_t i, j, k, n; glm::length_t i, j, k, n;
size_t varCount = m_VariationList.Size(); size_t varCount = m_VariationList.Size();
Palette<T> palette; Palette<T> palette;
static size_t xformDistrib[] = static size_t xformDistrib[] =
{ {
2, 2, 2, 2, 2, 2, 2, 2,
@ -632,15 +613,14 @@ public:
5, 5, 5, 5,
6 6
}; };
ember.Clear(); ember.Clear();
if (m_PaletteList.Size()) if (m_PaletteList.Size())
ember.m_Palette = *m_PaletteList.GetRandomPalette(); ember.m_Palette = *m_PaletteList.GetRandomPalette();
ember.m_Time = 0; ember.m_Time = 0;
ember.m_Interp = EMBER_INTERP_LINEAR; ember.m_Interp = eInterp::EMBER_INTERP_LINEAR;
ember.m_PaletteInterp = INTERP_HSV; ember.m_PaletteInterp = ePaletteInterp::INTERP_HSV;
//Choose the number of xforms. //Choose the number of xforms.
if (specXforms > 0) if (specXforms > 0)
@ -655,7 +635,6 @@ public:
if (addfinal) if (addfinal)
{ {
Xform<T> xform; Xform<T> xform;
xform.m_Affine.A(T(1.1));//Just put something in there so it doesn't show up as being an empty final xform. xform.m_Affine.A(T(1.1));//Just put something in there so it doesn't show up as being an empty final xform.
ember.SetFinalXform(xform); ember.SetFinalXform(xform);
} }
@ -676,7 +655,6 @@ public:
for (i = 0; i < ember.TotalXformCount(); i++) for (i = 0; i < ember.TotalXformCount(); i++)
{ {
Xform<T>* xform = ember.GetTotalXform(i); Xform<T>* xform = ember.GetTotalXform(i);
xform->m_Weight = T(1) / ember.TotalXformCount(); 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_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. xform->m_ColorY = m_Rand.Frand01<T>();//Will need to update this if 2D coordinates are ever supported.
@ -733,6 +711,7 @@ public:
//but less than varCount. Probability leans //but less than varCount. Probability leans
//towards fewer variations. //towards fewer variations.
n = 2; n = 2;
while (m_Rand.RandBit() && (n < varCount)) while (m_Rand.RandBit() && (n < varCount))
n++; n++;
@ -821,7 +800,6 @@ public:
size_t i; size_t i;
T best, b; T best, b;
Ember<T> bestEmber = ember; Ember<T> bestEmber = ember;
best = TryColors(ember, colorResolution); best = TryColors(ember, colorResolution);
if (best < 0) if (best < 0)
@ -864,11 +842,9 @@ public:
size_t pixTotal, res3 = res * res * res; size_t pixTotal, res3 = res * res * res;
T scalar; T scalar;
Ember<T> adjustedEmber = ember; Ember<T> adjustedEmber = ember;
adjustedEmber.m_Quality = 1; adjustedEmber.m_Quality = 1;
adjustedEmber.m_Supersample = 1; adjustedEmber.m_Supersample = 1;
adjustedEmber.m_MaxRadDE = 0; adjustedEmber.m_MaxRadDE = 0;
//Scale the image so that the total number of pixels is ~10,000. //Scale the image so that the total number of pixels is ~10,000.
pixTotal = ember.m_FinalRasW * ember.m_FinalRasH; pixTotal = ember.m_FinalRasW * ember.m_FinalRasH;
scalar = std::sqrt(T(10000) / pixTotal); scalar = std::sqrt(T(10000) / pixTotal);
@ -876,7 +852,6 @@ public:
adjustedEmber.m_FinalRasH = static_cast<size_t>(ember.m_FinalRasH * scalar); adjustedEmber.m_FinalRasH = static_cast<size_t>(ember.m_FinalRasH * scalar);
adjustedEmber.m_PixelsPerUnit *= scalar; adjustedEmber.m_PixelsPerUnit *= scalar;
adjustedEmber.m_TemporalSamples = 1; adjustedEmber.m_TemporalSamples = 1;
m_Renderer->SetEmber(adjustedEmber); m_Renderer->SetEmber(adjustedEmber);
m_Renderer->BytesPerChannel(1); m_Renderer->BytesPerChannel(1);
m_Renderer->EarlyClip(true); m_Renderer->EarlyClip(true);
@ -884,7 +859,7 @@ public:
m_Renderer->ThreadCount(Timing::ProcessorCount()); m_Renderer->ThreadCount(Timing::ProcessorCount());
m_Renderer->Callback(nullptr); m_Renderer->Callback(nullptr);
if (m_Renderer->Run(m_FinalImage) != RENDER_OK) if (m_Renderer->Run(m_FinalImage) != eRenderStatus::RENDER_OK)
{ {
cout << "Error rendering test image for TryColors(). Aborting." << endl; cout << "Error rendering test image for TryColors(). Aborting." << endl;
return -1; return -1;
@ -892,7 +867,6 @@ public:
m_Hist.resize(res3); m_Hist.resize(res3);
memset(m_Hist.data(), 0, res3); memset(m_Hist.data(), 0, res3);
p = m_FinalImage.data(); p = m_FinalImage.data();
for (i = 0; i < m_Renderer->FinalDimensions(); i++) for (i = 0; i < m_Renderer->FinalDimensions(); i++)
@ -1052,17 +1026,13 @@ public:
{ {
//Align what's going to be interpolated. //Align what's going to be interpolated.
Interpolater<T>::Align(prealign, spun, 2); Interpolater<T>::Align(prealign, spun, 2);
spun[0].m_Time = 0; spun[0].m_Time = 0;
spun[1].m_Time = 1; spun[1].m_Time = 1;
//Call this first to establish the asymmetric reference angles. //Call this first to establish the asymmetric reference angles.
Interpolater<T>::AsymmetricRefAngles(spun, 2); Interpolater<T>::AsymmetricRefAngles(spun, 2);
//Rotate the aligned xforms. //Rotate the aligned xforms.
spun[0].RotateAffines(-blend * 360); spun[0].RotateAffines(-blend * 360);
spun[1].RotateAffines(-blend * 360); spun[1].RotateAffines(-blend * 360);
Interpolater<T>::Interpolate(spun, 2, m_Smooth ? Interpolater<T>::Smoother(blend) : blend, m_Stagger, result); Interpolater<T>::Interpolate(spun, 2, m_Smooth ? Interpolater<T>::Smoother(blend) : blend, m_Stagger, result);
} }
@ -1084,7 +1054,6 @@ public:
void Spin(Ember<T>& parent, Ember<T>* templ, Ember<T>& result, size_t frame, T blend) void Spin(Ember<T>& parent, Ember<T>* templ, Ember<T>& result, size_t frame, T blend)
{ {
char temp[50]; char temp[50];
//Spin the parent blend degrees. //Spin the parent blend degrees.
Loop(parent, result, blend); Loop(parent, result, blend);
@ -1094,17 +1063,14 @@ public:
//Set ember parameters accordingly. //Set ember parameters accordingly.
result.m_Time = T(frame); result.m_Time = T(frame);
result.m_Interp = EMBER_INTERP_LINEAR; result.m_Interp = eInterp::EMBER_INTERP_LINEAR;
result.m_PaletteInterp = INTERP_HSV; result.m_PaletteInterp = ePaletteInterp::INTERP_HSV;
//Create the edit doc xml. //Create the edit doc xml.
sprintf_s(temp, 50, "rotate %g", blend * 360.0); sprintf_s(temp, 50, "rotate %g", blend * 360.0);
result.ClearEdit(); result.ClearEdit();
result.m_Edits = m_EmberToXml.CreateNewEditdoc(&parent, nullptr, temp, m_Nick, m_Url, m_Id, m_Comment, m_SheepGen, m_SheepId); result.m_Edits = m_EmberToXml.CreateNewEditdoc(&parent, nullptr, temp, m_Nick, m_Url, m_Id, m_Comment, m_SheepGen, m_SheepId);
//Subpixel jitter. //Subpixel jitter.
Offset(result, m_OffsetX, m_OffsetY); Offset(result, m_OffsetX, m_OffsetY);
//Make the name of the flame the time. //Make the name of the flame the time.
sprintf_s(temp, 50, "%f", result.m_Time); sprintf_s(temp, 50, "%f", result.m_Time);
result.m_Name = string(temp); result.m_Name = string(temp);
@ -1125,7 +1091,6 @@ public:
void SpinInter(Ember<T>* parents, Ember<T>* templ, Ember<T>& result, size_t frame, bool seqFlag, T blend) void SpinInter(Ember<T>* parents, Ember<T>* templ, Ember<T>& result, size_t frame, bool seqFlag, T blend)
{ {
char temp[50]; char temp[50];
//Interpolate between spun parents. //Interpolate between spun parents.
Edge(parents, result, blend, seqFlag); Edge(parents, result, blend, seqFlag);
@ -1137,15 +1102,12 @@ public:
//Set ember parameters accordingly. //Set ember parameters accordingly.
result.m_Time = T(frame); result.m_Time = T(frame);
//Create the edit doc xml. //Create the edit doc xml.
sprintf_s(temp, 50, "interpolate %g", blend * 360.0); sprintf_s(temp, 50, "interpolate %g", blend * 360.0);
result.ClearEdit(); result.ClearEdit();
result.m_Edits = m_EmberToXml.CreateNewEditdoc(&parents[0], &parents[1], temp, m_Nick, m_Url, m_Id, m_Comment, m_SheepGen, m_SheepId); 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. //Subpixel jitter.
Offset(result, m_OffsetX, m_OffsetY); Offset(result, m_OffsetX, m_OffsetY);
//Make the name of the flame the time. //Make the name of the flame the time.
sprintf_s(temp, 50, "%f", result.m_Time); sprintf_s(temp, 50, "%f", result.m_Time);
result.m_Name = string(temp); result.m_Name = string(temp);
@ -1200,16 +1162,16 @@ public:
if (templ.m_GammaThresh >= 0) if (templ.m_GammaThresh >= 0)
ember.m_GammaThresh = templ.m_GammaThresh; ember.m_GammaThresh = templ.m_GammaThresh;
if (templ.m_SpatialFilterType > 0) if (templ.m_SpatialFilterType > eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER)
ember.m_SpatialFilterType = templ.m_SpatialFilterType; ember.m_SpatialFilterType = templ.m_SpatialFilterType;
if (templ.m_Interp >= 0) if (templ.m_Interp >= eInterp::EMBER_INTERP_LINEAR)
ember.m_Interp = templ.m_Interp; ember.m_Interp = templ.m_Interp;
if (templ.m_AffineInterp >= 0) if (templ.m_AffineInterp >= eAffineInterp::AFFINE_INTERP_LINEAR)
ember.m_AffineInterp = templ.m_AffineInterp; ember.m_AffineInterp = templ.m_AffineInterp;
if (templ.m_TemporalFilterType >= 0) if (templ.m_TemporalFilterType >= eTemporalFilterType::BOX_TEMPORAL_FILTER)
ember.m_TemporalFilterType = templ.m_TemporalFilterType; ember.m_TemporalFilterType = templ.m_TemporalFilterType;
if (templ.m_TemporalFilterWidth > 0) if (templ.m_TemporalFilterWidth > 0)
@ -1221,7 +1183,7 @@ public:
if (templ.m_HighlightPower >= 0) if (templ.m_HighlightPower >= 0)
ember.m_HighlightPower = templ.m_HighlightPower; ember.m_HighlightPower = templ.m_HighlightPower;
if (templ.m_PaletteMode >= 0) if (templ.m_PaletteMode >= ePaletteMode::PALETTE_STEP)
ember.m_PaletteMode = templ.m_PaletteMode; ember.m_PaletteMode = templ.m_PaletteMode;
} }
@ -1254,7 +1216,6 @@ public:
T th = by * 2 * T(M_PI) / 360; T th = by * 2 * T(M_PI) / 360;
T c = std::cos(th); T c = std::cos(th);
T s = -std::sin(th); T s = -std::sin(th);
newCenterX -= oldCenterX; newCenterX -= oldCenterX;
newCenterY -= oldCenterY; newCenterY -= oldCenterY;
r[0] = c * newCenterX - s * newCenterY; r[0] = c * newCenterX - s * newCenterY;
@ -1279,7 +1240,6 @@ public:
size_t i, lowTarget, highTarget; size_t i, lowTarget, highTarget;
T min[2], max[2]; T min[2], max[2];
IterParams<T> params; IterParams<T> params;
m_Renderer->SetEmber(ember); m_Renderer->SetEmber(ember);
m_Renderer->CreateSpatialFilter(newAlloc); m_Renderer->CreateSpatialFilter(newAlloc);
m_Renderer->CreateDEFilter(newAlloc); m_Renderer->CreateDEFilter(newAlloc);
@ -1298,7 +1258,6 @@ public:
params.m_Skip = 20; params.m_Skip = 20;
//params.m_OneColDiv2 = m_Renderer->CoordMap().OneCol() / 2; //params.m_OneColDiv2 = m_Renderer->CoordMap().OneCol() / 2;
//params.m_OneRowDiv2 = m_Renderer->CoordMap().OneRow() / 2; //params.m_OneRowDiv2 = m_Renderer->CoordMap().OneRow() / 2;
size_t bv = m_Iterator->Iterate(ember, params, m_Samples.data(), m_Rand);//Use a special fuse of 20, all other calls to this will use 15, or 100. size_t bv = m_Iterator->Iterate(ember, params, 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 / T(samples) > eps)
@ -1309,15 +1268,17 @@ public:
lowTarget = static_cast<size_t>(samples * eps); lowTarget = static_cast<size_t>(samples * eps);
highTarget = samples - lowTarget; highTarget = samples - lowTarget;
min[0] = min[1] = 1e10; min[0] = min[1] = 1e10;
max[0] = max[1] = -1e10; max[0] = max[1] = -1e10;
for (i = 0; i < samples; i++) for (i = 0; i < samples; i++)
{ {
if (m_Samples[i].m_X < min[0]) min[0] = m_Samples[i].m_X; if (m_Samples[i].m_X < min[0]) min[0] = m_Samples[i].m_X;
if (m_Samples[i].m_Y < min[1]) min[1] = m_Samples[i].m_Y; if (m_Samples[i].m_Y < min[1]) min[1] = m_Samples[i].m_Y;
if (m_Samples[i].m_X > max[0]) max[0] = m_Samples[i].m_X; if (m_Samples[i].m_X > max[0]) max[0] = m_Samples[i].m_X;
if (m_Samples[i].m_Y > max[1]) max[1] = m_Samples[i].m_Y; if (m_Samples[i].m_Y > max[1]) max[1] = m_Samples[i].m_Y;
} }
@ -1327,18 +1288,15 @@ public:
bmin[1] = min[1]; bmin[1] = min[1];
bmax[0] = max[0]; bmax[0] = max[0];
bmax[1] = max[1]; bmax[1] = max[1];
return bv; return bv;
} }
std::sort(m_Samples.begin(), m_Samples.end(), &SortPointByX<T>); std::sort(m_Samples.begin(), m_Samples.end(), &SortPointByX<T>);
bmin[0] = m_Samples[lowTarget].m_X; bmin[0] = m_Samples[lowTarget].m_X;
bmax[0] = m_Samples[highTarget].m_X; bmax[0] = m_Samples[highTarget].m_X;
std::sort(m_Samples.begin(), m_Samples.end(), &SortPointByY<T>); std::sort(m_Samples.begin(), m_Samples.end(), &SortPointByY<T>);
bmin[1] = m_Samples[lowTarget + 1].m_Y; bmin[1] = m_Samples[lowTarget + 1].m_Y;
bmax[1] = m_Samples[highTarget + 1].m_Y; bmax[1] = m_Samples[highTarget + 1].m_Y;
return bv; return bv;
} }

View File

@ -11,22 +11,22 @@ namespace EmberNs
/// <summary> /// <summary>
/// The types of spatial filters available. /// The types of spatial filters available.
/// </summary> /// </summary>
enum eSpatialFilterType enum class eSpatialFilterType : size_t
{ {
GAUSSIAN_SPATIAL_FILTER = 0, GAUSSIAN_SPATIAL_FILTER,
HERMITE_SPATIAL_FILTER = 1, HERMITE_SPATIAL_FILTER,
BOX_SPATIAL_FILTER = 2, BOX_SPATIAL_FILTER,
TRIANGLE_SPATIAL_FILTER = 3, TRIANGLE_SPATIAL_FILTER,
BELL_SPATIAL_FILTER = 4, BELL_SPATIAL_FILTER,
BSPLINE_SPATIAL_FILTER = 5, BSPLINE_SPATIAL_FILTER,
LANCZOS3_SPATIAL_FILTER = 6, LANCZOS3_SPATIAL_FILTER,
LANCZOS2_SPATIAL_FILTER = 7, LANCZOS2_SPATIAL_FILTER,
MITCHELL_SPATIAL_FILTER = 8, MITCHELL_SPATIAL_FILTER,
BLACKMAN_SPATIAL_FILTER = 9, BLACKMAN_SPATIAL_FILTER,
CATROM_SPATIAL_FILTER = 10, CATROM_SPATIAL_FILTER,
HAMMING_SPATIAL_FILTER = 11, HAMMING_SPATIAL_FILTER,
HANNING_SPATIAL_FILTER = 12, HANNING_SPATIAL_FILTER,
QUADRATIC_SPATIAL_FILTER = 13 QUADRATIC_SPATIAL_FILTER
}; };
/// <summary> /// <summary>
@ -109,7 +109,6 @@ public:
{ {
T fw = T(2.0) * m_Support * m_Supersample * m_FilterRadius / m_PixelAspectRatio; T fw = T(2.0) * m_Support * m_Supersample * m_FilterRadius / m_PixelAspectRatio;
T adjust, ii, jj; T adjust, ii, jj;
int fwidth = int(fw) + 1; int fwidth = int(fw) + 1;
int i, j; int i, j;
@ -133,10 +132,8 @@ public:
//Calculate the function inputs for the kernel function. //Calculate the function inputs for the kernel function.
ii = ((T(2.0) * i + T(1.0)) / T(fwidth) - T(1.0)) * adjust; 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; jj = ((T(2.0) * j + T(1.0)) / T(fwidth) - T(1.0)) * adjust;
//Adjust for aspect ratio. //Adjust for aspect ratio.
jj /= m_PixelAspectRatio; jj /= m_PixelAspectRatio;
m_Filter[i + j * fwidth] = Filter(ii) * Filter(jj);//Call virtual Filter(), implemented in specific derived filter classes. m_Filter[i + j * fwidth] = Filter(ii) * Filter(jj);//Call virtual Filter(), implemented in specific derived filter classes.
} }
} }
@ -149,7 +146,8 @@ public:
} }
m_FilterRadius += T(0.01);//Values were too small. m_FilterRadius += T(0.01);//Values were too small.
} while (1); }
while (1);
} }
/// <summary> /// <summary>
@ -160,7 +158,6 @@ public:
{ {
size_t i; size_t i;
stringstream ss; stringstream ss;
ss ss
<< "Spatial Filter:" << endl << "Spatial Filter:" << endl
<< " Support: " << m_Support << endl << " Support: " << m_Support << endl
@ -169,7 +166,6 @@ public:
<< "Pixel aspect ratio: " << m_PixelAspectRatio << endl << "Pixel aspect ratio: " << m_PixelAspectRatio << endl
<< "Final filter width: " << m_FinalFilterWidth << endl << "Final filter width: " << m_FinalFilterWidth << endl
<< "Filter buffer size: " << m_Filter.size() << endl; << "Filter buffer size: " << m_Filter.size() << endl;
ss << "Filter: " << endl; ss << "Filter: " << endl;
for (i = 0; i < m_Filter.size(); i++) for (i = 0; i < m_Filter.size(); i++)
@ -260,7 +256,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) GaussianFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(GAUSSIAN_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Gaussian filter to t parameter and return. /// Apply Gaussian filter to t parameter and return.
@ -288,7 +284,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) HermiteFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(HERMITE_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::HERMITE_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Hermite filter to t parameter and return. /// Apply Hermite filter to t parameter and return.
@ -323,7 +319,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) BoxFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(BOX_SPATIAL_FILTER, T(0.5), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::BOX_SPATIAL_FILTER, T(0.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Box filter to t parameter and return. /// Apply Box filter to t parameter and return.
@ -354,7 +350,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) TriangleFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(TRIANGLE_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::TRIANGLE_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Triangle filter to t parameter and return. /// Apply Triangle filter to t parameter and return.
@ -388,7 +384,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) BellFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(BELL_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::BELL_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Bell filter to t parameter and return. /// Apply Bell filter to t parameter and return.
@ -429,7 +425,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) BsplineFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(BSPLINE_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::BSPLINE_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply B Spline filter to t parameter and return. /// Apply B Spline filter to t parameter and return.
@ -474,7 +470,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) Lanczos3Filter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(LANCZOS3_SPATIAL_FILTER, T(3.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::LANCZOS3_SPATIAL_FILTER, T(3.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Lanczos 3 filter to t parameter and return. /// Apply Lanczos 3 filter to t parameter and return.
@ -508,7 +504,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) Lanczos2Filter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(LANCZOS2_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::LANCZOS2_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Lanczos 2 filter to t parameter and return. /// Apply Lanczos 2 filter to t parameter and return.
@ -542,7 +538,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) MitchellFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(MITCHELL_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::MITCHELL_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Mitchell filter to t parameter and return. /// Apply Mitchell filter to t parameter and return.
@ -563,7 +559,6 @@ public:
t = (((T(12.0) - T(9.0) * b - T(6.0) * c) * (t * tt)) t = (((T(12.0) - T(9.0) * b - T(6.0) * c) * (t * tt))
+ ((T(-18.0) + T(12.0) * b + T(6.0) * c) * tt) + ((T(-18.0) + T(12.0) * b + T(6.0) * c) * tt)
+ (T(6.0) - 2 * b)); + (T(6.0) - 2 * b));
return t / 6; return t / 6;
} }
else if (t < 2) else if (t < 2)
@ -572,7 +567,6 @@ public:
+ ((T(6.0) * b + T(30.0) * c) * tt) + ((T(6.0) * b + T(30.0) * c) * tt)
+ ((T(-12.0) * b - T(48.0) * c) * t) + ((T(-12.0) * b - T(48.0) * c) * t)
+ (T(8.0) * b + 24 * c)); + (T(8.0) * b + 24 * c));
return t / 6; return t / 6;
} }
@ -595,7 +589,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) BlackmanFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(BLACKMAN_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::BLACKMAN_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Blackman filter to t parameter and return. /// Apply Blackman filter to t parameter and return.
@ -623,7 +617,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) CatromFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(CATROM_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::CATROM_SPATIAL_FILTER, T(2.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Catmull-Rom filter to t parameter and return. /// Apply Catmull-Rom filter to t parameter and return.
@ -666,7 +660,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) HammingFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(HAMMING_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::HAMMING_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Hamming filter to t parameter and return. /// Apply Hamming filter to t parameter and return.
@ -694,7 +688,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) HanningFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(HANNING_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::HANNING_SPATIAL_FILTER, T(1.0), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Hanning filter to t parameter and return. /// Apply Hanning filter to t parameter and return.
@ -722,7 +716,7 @@ public:
/// <param name="superSample">The supersample of the ember being rendered</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> /// <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)) QuadraticFilter(T filterRadius, size_t superSample, T pixelAspectRatio = T(1.0))
: SpatialFilter<T>(QUADRATIC_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { } : SpatialFilter<T>(eSpatialFilterType::QUADRATIC_SPATIAL_FILTER, T(1.5), filterRadius, superSample, pixelAspectRatio) { }
/// <summary> /// <summary>
/// Apply Quadratic filter to t parameter and return. /// Apply Quadratic filter to t parameter and return.
@ -766,36 +760,68 @@ public:
{ {
SpatialFilter<T>* filter = nullptr; SpatialFilter<T>* filter = nullptr;
if (filterType == GAUSSIAN_SPATIAL_FILTER) switch (filterType)
{
case EmberNs::eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER:
filter = new GaussianFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new GaussianFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == HERMITE_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::HERMITE_SPATIAL_FILTER:
filter = new HermiteFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new HermiteFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == BOX_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BOX_SPATIAL_FILTER:
filter = new BoxFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new BoxFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == TRIANGLE_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::TRIANGLE_SPATIAL_FILTER:
filter = new TriangleFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new TriangleFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == BELL_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BELL_SPATIAL_FILTER:
filter = new BellFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new BellFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == BSPLINE_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BSPLINE_SPATIAL_FILTER:
filter = new BsplineFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new BsplineFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == LANCZOS3_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::LANCZOS3_SPATIAL_FILTER:
filter = new Lanczos3Filter<T>(filterRadius, superSample, pixelAspectRatio); filter = new Lanczos3Filter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == LANCZOS2_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::LANCZOS2_SPATIAL_FILTER:
filter = new Lanczos2Filter<T>(filterRadius, superSample, pixelAspectRatio); filter = new Lanczos2Filter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == MITCHELL_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::MITCHELL_SPATIAL_FILTER:
filter = new MitchellFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new MitchellFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == BLACKMAN_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BLACKMAN_SPATIAL_FILTER:
filter = new BlackmanFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new BlackmanFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == CATROM_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::CATROM_SPATIAL_FILTER:
filter = new CatromFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new CatromFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == HAMMING_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::HAMMING_SPATIAL_FILTER:
filter = new HammingFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new HammingFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == HANNING_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::HANNING_SPATIAL_FILTER:
filter = new HanningFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new HanningFilter<T>(filterRadius, superSample, pixelAspectRatio);
else if (filterType == QUADRATIC_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::QUADRATIC_SPATIAL_FILTER:
filter = new QuadraticFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new QuadraticFilter<T>(filterRadius, superSample, pixelAspectRatio);
else break;
default:
filter = new GaussianFilter<T>(filterRadius, superSample, pixelAspectRatio); filter = new GaussianFilter<T>(filterRadius, superSample, pixelAspectRatio);
break;
}
if (filter) if (filter)
filter->Create(); filter->Create();
@ -810,7 +836,6 @@ public:
static vector<string> FilterTypes() static vector<string> FilterTypes()
{ {
vector<string> v; vector<string> v;
v.reserve(14); v.reserve(14);
v.push_back("Gaussian"); v.push_back("Gaussian");
v.push_back("Hermite"); v.push_back("Hermite");
@ -826,7 +851,6 @@ public:
v.push_back("Hamming"); v.push_back("Hamming");
v.push_back("Hanning"); v.push_back("Hanning");
v.push_back("Quadratic"); v.push_back("Quadratic");
return v; return v;
} }
@ -838,35 +862,35 @@ public:
static eSpatialFilterType FromString(const string& filterType) static eSpatialFilterType FromString(const string& filterType)
{ {
if (!_stricmp(filterType.c_str(), "Gaussian")) if (!_stricmp(filterType.c_str(), "Gaussian"))
return GAUSSIAN_SPATIAL_FILTER; return eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Hermite")) else if (!_stricmp(filterType.c_str(), "Hermite"))
return HERMITE_SPATIAL_FILTER; return eSpatialFilterType::HERMITE_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Box")) else if (!_stricmp(filterType.c_str(), "Box"))
return BOX_SPATIAL_FILTER; return eSpatialFilterType::BOX_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Triangle")) else if (!_stricmp(filterType.c_str(), "Triangle"))
return TRIANGLE_SPATIAL_FILTER; return eSpatialFilterType::TRIANGLE_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Bell")) else if (!_stricmp(filterType.c_str(), "Bell"))
return BELL_SPATIAL_FILTER; return eSpatialFilterType::BELL_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Bspline")) else if (!_stricmp(filterType.c_str(), "Bspline"))
return BSPLINE_SPATIAL_FILTER; return eSpatialFilterType::BSPLINE_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Lanczos3")) else if (!_stricmp(filterType.c_str(), "Lanczos3"))
return LANCZOS3_SPATIAL_FILTER; return eSpatialFilterType::LANCZOS3_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Lanczos2")) else if (!_stricmp(filterType.c_str(), "Lanczos2"))
return LANCZOS2_SPATIAL_FILTER; return eSpatialFilterType::LANCZOS2_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Mitchell")) else if (!_stricmp(filterType.c_str(), "Mitchell"))
return MITCHELL_SPATIAL_FILTER; return eSpatialFilterType::MITCHELL_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Blackman")) else if (!_stricmp(filterType.c_str(), "Blackman"))
return BLACKMAN_SPATIAL_FILTER; return eSpatialFilterType::BLACKMAN_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Catrom")) else if (!_stricmp(filterType.c_str(), "Catrom"))
return CATROM_SPATIAL_FILTER; return eSpatialFilterType::CATROM_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Hamming")) else if (!_stricmp(filterType.c_str(), "Hamming"))
return HAMMING_SPATIAL_FILTER; return eSpatialFilterType::HAMMING_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Hanning")) else if (!_stricmp(filterType.c_str(), "Hanning"))
return HANNING_SPATIAL_FILTER; return eSpatialFilterType::HANNING_SPATIAL_FILTER;
else if (!_stricmp(filterType.c_str(), "Quadratic")) else if (!_stricmp(filterType.c_str(), "Quadratic"))
return QUADRATIC_SPATIAL_FILTER; return eSpatialFilterType::QUADRATIC_SPATIAL_FILTER;
else else
return GAUSSIAN_SPATIAL_FILTER; return eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER;
} }
/// <summary> /// <summary>
@ -878,38 +902,82 @@ public:
{ {
string filter; string filter;
if (filterType == GAUSSIAN_SPATIAL_FILTER) switch (filterType)
{
case EmberNs::eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER:
filter = "Gaussian"; filter = "Gaussian";
else if (filterType == HERMITE_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::HERMITE_SPATIAL_FILTER:
filter = "Hermite"; filter = "Hermite";
else if (filterType == BOX_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BOX_SPATIAL_FILTER:
filter = "Box"; filter = "Box";
else if (filterType == TRIANGLE_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::TRIANGLE_SPATIAL_FILTER:
filter = "Triangle"; filter = "Triangle";
else if (filterType == BELL_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BELL_SPATIAL_FILTER:
filter = "Bell"; filter = "Bell";
else if (filterType == BSPLINE_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BSPLINE_SPATIAL_FILTER:
filter = "Bspline"; filter = "Bspline";
else if (filterType == LANCZOS3_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::LANCZOS3_SPATIAL_FILTER:
filter = "Lanczos3"; filter = "Lanczos3";
else if (filterType == LANCZOS2_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::LANCZOS2_SPATIAL_FILTER:
filter = "Lanczos2"; filter = "Lanczos2";
else if (filterType == MITCHELL_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::MITCHELL_SPATIAL_FILTER:
filter = "Mitchell"; filter = "Mitchell";
else if (filterType == BLACKMAN_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::BLACKMAN_SPATIAL_FILTER:
filter = "Blackman"; filter = "Blackman";
else if (filterType == CATROM_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::CATROM_SPATIAL_FILTER:
filter = "Catrom"; filter = "Catrom";
else if (filterType == HAMMING_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::HAMMING_SPATIAL_FILTER:
filter = "Hamming"; filter = "Hamming";
else if (filterType == HANNING_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::HANNING_SPATIAL_FILTER:
filter = "Hanning"; filter = "Hanning";
else if (filterType == QUADRATIC_SPATIAL_FILTER) break;
case EmberNs::eSpatialFilterType::QUADRATIC_SPATIAL_FILTER:
filter = "Quadratic"; filter = "Quadratic";
else break;
default:
filter = "Gaussian"; filter = "Gaussian";
break;
}
return filter; return filter;
} }
}; };
/// <summary>
/// Thin wrapper around SpatialFilterCreator::ToString() to allow << operator on spatial filter type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const eSpatialFilterType& t)
{
stream << SpatialFilterCreator<float>::ToString(t);
return stream;
}
} }

View File

@ -11,11 +11,11 @@ namespace EmberNs
/// <summary> /// <summary>
/// The types of temporal filters available. /// The types of temporal filters available.
/// </summary> /// </summary>
enum eTemporalFilterType enum class eTemporalFilterType : size_t
{ {
BOX_TEMPORAL_FILTER = 0, BOX_TEMPORAL_FILTER,
GAUSSIAN_TEMPORAL_FILTER = 1, GAUSSIAN_TEMPORAL_FILTER,
EXP_TEMPORAL_FILTER = 2 EXP_TEMPORAL_FILTER
}; };
/// <summary> /// <summary>
@ -49,7 +49,6 @@ public:
TemporalFilter(eTemporalFilterType filterType, size_t temporalSamples, T filterWidth) TemporalFilter(eTemporalFilterType filterType, size_t temporalSamples, T filterWidth)
{ {
size_t i, steps = temporalSamples; size_t i, steps = temporalSamples;
m_TemporalSamples = temporalSamples; m_TemporalSamples = temporalSamples;
m_FilterWidth = filterWidth; m_FilterWidth = filterWidth;
m_Deltas.resize(steps); m_Deltas.resize(steps);
@ -116,12 +115,10 @@ public:
{ {
size_t i; size_t i;
stringstream ss; stringstream ss;
ss << "Temporal Filter:" << endl ss << "Temporal Filter:" << endl
<< " Size: " << Size() << endl << " Size: " << Size() << endl
<< " Type: " << TemporalFilterCreator<T>::ToString(m_FilterType) << endl << " Type: " << TemporalFilterCreator<T>::ToString(m_FilterType) << endl
<< " Sum Filt: " << SumFilt() << endl; << " Sum Filt: " << SumFilt() << endl;
ss << "Deltas: " << endl; ss << "Deltas: " << endl;
for (i = 0; i < m_Deltas.size(); i++) for (i = 0; i < m_Deltas.size(); i++)
@ -184,7 +181,7 @@ protected:
template <typename T> template <typename T>
class EMBER_API ExpTemporalFilter : public TemporalFilter<T> class EMBER_API ExpTemporalFilter : public TemporalFilter<T>
{ {
TEMPORALFILTERUSINGS TEMPORALFILTERUSINGS
public: public:
/// <summary> /// <summary>
/// Constructor to create an Exp filter. /// Constructor to create an Exp filter.
@ -193,7 +190,7 @@ public:
/// <param name="filterWidth">The width of the filter.</param> /// <param name="filterWidth">The width of the filter.</param>
/// <param name="filterExp">The filter exp.</param> /// <param name="filterExp">The filter exp.</param>
ExpTemporalFilter(size_t temporalSamples, T filterWidth, T filterExp) ExpTemporalFilter(size_t temporalSamples, T filterWidth, T filterExp)
: TemporalFilter<T>(BOX_TEMPORAL_FILTER, temporalSamples, filterWidth) : TemporalFilter<T>(eTemporalFilterType::BOX_TEMPORAL_FILTER, temporalSamples, filterWidth)
{ {
if (Size() > 1) if (Size() > 1)
{ {
@ -226,7 +223,7 @@ public:
template <typename T> template <typename T>
class EMBER_API GaussianTemporalFilter : public TemporalFilter<T> class EMBER_API GaussianTemporalFilter : public TemporalFilter<T>
{ {
TEMPORALFILTERUSINGS TEMPORALFILTERUSINGS
public: public:
/// <summary> /// <summary>
/// Constructor to create a Gaussian filter. /// Constructor to create a Gaussian filter.
@ -234,7 +231,7 @@ public:
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</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="filterWidth">The width of the filter.</param>
GaussianTemporalFilter(size_t temporalSamples, T filterWidth) GaussianTemporalFilter(size_t temporalSamples, T filterWidth)
: TemporalFilter<T>(GAUSSIAN_TEMPORAL_FILTER, temporalSamples, filterWidth) : TemporalFilter<T>(eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER, temporalSamples, filterWidth)
{ {
if (Size() > 1) if (Size() > 1)
{ {
@ -261,7 +258,7 @@ public:
template <typename T> template <typename T>
class EMBER_API BoxTemporalFilter : public TemporalFilter<T> class EMBER_API BoxTemporalFilter : public TemporalFilter<T>
{ {
TEMPORALFILTERUSINGS TEMPORALFILTERUSINGS
public: public:
/// <summary> /// <summary>
/// Constructor to create a Box filter. /// Constructor to create a Box filter.
@ -269,7 +266,7 @@ public:
/// <param name="temporalSamples">The number of temporal samples in the ember being rendered</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="filterWidth">The width of the filter.</param>
BoxTemporalFilter(size_t temporalSamples, T filterWidth) BoxTemporalFilter(size_t temporalSamples, T filterWidth)
: TemporalFilter<T>(BOX_TEMPORAL_FILTER, temporalSamples, filterWidth) : TemporalFilter<T>(eTemporalFilterType::BOX_TEMPORAL_FILTER, temporalSamples, filterWidth)
{ {
if (Size() > 1) if (Size() > 1)
{ {
@ -300,14 +297,24 @@ public:
{ {
TemporalFilter<T>* filter = nullptr; TemporalFilter<T>* filter = nullptr;
if (filterType == BOX_TEMPORAL_FILTER) switch (filterType)
{
case EmberNs::eTemporalFilterType::BOX_TEMPORAL_FILTER:
filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth); filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth);
else if (filterType == GAUSSIAN_TEMPORAL_FILTER) break;
case EmberNs::eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER:
filter = new GaussianTemporalFilter<T>(temporalSamples, filterWidth); filter = new GaussianTemporalFilter<T>(temporalSamples, filterWidth);
else if (filterType == EXP_TEMPORAL_FILTER) break;
case EmberNs::eTemporalFilterType::EXP_TEMPORAL_FILTER:
filter = new ExpTemporalFilter<T>(temporalSamples, filterWidth, filterExp); filter = new ExpTemporalFilter<T>(temporalSamples, filterWidth, filterExp);
else break;
default:
filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth);//Default to box if bad enum passed in. filter = new BoxTemporalFilter<T>(temporalSamples, filterWidth);//Default to box if bad enum passed in.
break;
}
return filter; return filter;
} }
@ -319,12 +326,10 @@ public:
static vector<string> FilterTypes() static vector<string> FilterTypes()
{ {
vector<string> v; vector<string> v;
v.reserve(3); v.reserve(3);
v.push_back("Box"); v.push_back("Box");
v.push_back("Gaussian"); v.push_back("Gaussian");
v.push_back("Exp"); v.push_back("Exp");
return v; return v;
} }
@ -336,13 +341,13 @@ public:
static eTemporalFilterType FromString(const string& filterType) static eTemporalFilterType FromString(const string& filterType)
{ {
if (!_stricmp(filterType.c_str(), "box")) if (!_stricmp(filterType.c_str(), "box"))
return BOX_TEMPORAL_FILTER; return eTemporalFilterType::BOX_TEMPORAL_FILTER;
else if (!_stricmp(filterType.c_str(), "gaussian")) else if (!_stricmp(filterType.c_str(), "gaussian"))
return GAUSSIAN_TEMPORAL_FILTER; return eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER;
else if (!_stricmp(filterType.c_str(), "exp")) else if (!_stricmp(filterType.c_str(), "exp"))
return EXP_TEMPORAL_FILTER; return eTemporalFilterType::EXP_TEMPORAL_FILTER;
else else
return BOX_TEMPORAL_FILTER; return eTemporalFilterType::BOX_TEMPORAL_FILTER;
} }
/// <summary> /// <summary>
@ -354,16 +359,38 @@ public:
{ {
string filter; string filter;
if (filterType == BOX_TEMPORAL_FILTER) switch (filterType)
{
case EmberNs::eTemporalFilterType::BOX_TEMPORAL_FILTER:
filter = "Box"; filter = "Box";
else if (filterType == GAUSSIAN_TEMPORAL_FILTER) break;
case EmberNs::eTemporalFilterType::GAUSSIAN_TEMPORAL_FILTER:
filter = "Gaussian"; filter = "Gaussian";
else if (filterType == EXP_TEMPORAL_FILTER) break;
case EmberNs::eTemporalFilterType::EXP_TEMPORAL_FILTER:
filter = "Exp"; filter = "Exp";
else break;
default:
filter = "Box"; filter = "Box";
break;
}
return filter; return filter;
} }
}; };
/// <summary>
/// Thin wrapper around TemporalFilterCreator::ToString() to allow << operator on temporal filter type.
/// </summary>
/// <param name="stream">The stream to insert into</param>
/// <param name="t">The type whose string representation will be inserted into the stream</param>
/// <returns></returns>
static std::ostream& operator<<(std::ostream& stream, const eTemporalFilterType& t)
{
stream << TemporalFilterCreator<float>::ToString(t);
return stream;
}
} }

View File

@ -255,7 +255,7 @@ public:
m_MotionOffset = EMPTYFIELD; m_MotionOffset = EMPTYFIELD;
} }
m_MotionFunc = MOTION_SIN; m_MotionFunc = eMotion::MOTION_SIN;
m_Motion.clear(); m_Motion.clear();
m_NeedPrecalcSumSquares = false; m_NeedPrecalcSumSquares = false;
m_NeedPrecalcSqrtSumSquares = false; m_NeedPrecalcSqrtSumSquares = false;

View File

@ -5,7 +5,7 @@
#include "VariationList.h" #include "VariationList.h"
#ifdef __APPLE__ #ifdef __APPLE__
#include <libgen.h> #include <libgen.h>
#endif #endif
/// <summary> /// <summary>
@ -174,14 +174,12 @@ public:
m_BadParamNames["exponentZ"] = "bubbleT3D_exponentZ"; m_BadParamNames["exponentZ"] = "bubbleT3D_exponentZ";
m_BadParamNames["_symmetryZ"] = "bubbleT3D_symmetryZ"; m_BadParamNames["_symmetryZ"] = "bubbleT3D_symmetryZ";
m_BadParamNames["_modusBlur"] = "bubbleT3D_modusBlur"; m_BadParamNames["_modusBlur"] = "bubbleT3D_modusBlur";
m_FlattenNames.reserve(24); m_FlattenNames.reserve(24);
m_FlattenNames.push_back("pre_crop"); m_FlattenNames.push_back("pre_crop");
m_FlattenNames.push_back("pre_falloff2"); m_FlattenNames.push_back("pre_falloff2");
m_FlattenNames.push_back("pre_rotate_x"); m_FlattenNames.push_back("pre_rotate_x");
m_FlattenNames.push_back("pre_rotate_y"); m_FlattenNames.push_back("pre_rotate_y");
m_FlattenNames.push_back("pre_ztranslate"); m_FlattenNames.push_back("pre_ztranslate");
m_FlattenNames.push_back("blur3D"); m_FlattenNames.push_back("blur3D");
m_FlattenNames.push_back("bubble"); m_FlattenNames.push_back("bubble");
m_FlattenNames.push_back("bwraps"); m_FlattenNames.push_back("bwraps");
@ -196,19 +194,14 @@ public:
m_FlattenNames.push_back("zblur"); m_FlattenNames.push_back("zblur");
m_FlattenNames.push_back("zcone"); m_FlattenNames.push_back("zcone");
m_FlattenNames.push_back("ztranslate"); m_FlattenNames.push_back("ztranslate");
m_FlattenNames.push_back("post_crop"); m_FlattenNames.push_back("post_crop");
m_FlattenNames.push_back("post_falloff2"); m_FlattenNames.push_back("post_falloff2");
m_FlattenNames.push_back("post_rotate_x"); m_FlattenNames.push_back("post_rotate_x");
m_FlattenNames.push_back("post_rotate_y"); m_FlattenNames.push_back("post_rotate_y");
m_FlattenNames.push_back("curl3D_cz"); m_FlattenNames.push_back("curl3D_cz");
//This is a vector of the param names as they are in the legacy, badly named flam3/Apophysis code. //This is a vector of the param names as they are in the legacy, badly named flam3/Apophysis code.
vector<string> badParams; vector<string> badParams;
badParams.reserve(6); badParams.reserve(6);
badParams.push_back("bwraps7_cellsize"); badParams.push_back("bwraps7_cellsize");
badParams.push_back("bwraps7_space"); badParams.push_back("bwraps7_space");
badParams.push_back("bwraps7_gain"); badParams.push_back("bwraps7_gain");
@ -216,7 +209,6 @@ public:
badParams.push_back("bwraps7_outer_twist"); badParams.push_back("bwraps7_outer_twist");
m_BadVariationNames.push_back(make_pair(make_pair(string("bwraps7"), string("bwraps")), badParams));//bwraps7 is the same as bwraps. m_BadVariationNames.push_back(make_pair(make_pair(string("bwraps7"), string("bwraps")), badParams));//bwraps7 is the same as bwraps.
badParams.clear(); badParams.clear();
badParams.push_back("bwraps2_cellsize"); badParams.push_back("bwraps2_cellsize");
badParams.push_back("bwraps2_space"); badParams.push_back("bwraps2_space");
badParams.push_back("bwraps2_gain"); badParams.push_back("bwraps2_gain");
@ -224,7 +216,6 @@ public:
badParams.push_back("bwraps2_outer_twist"); badParams.push_back("bwraps2_outer_twist");
m_BadVariationNames.push_back(make_pair(make_pair(string("bwraps2"), string("bwraps")), badParams));//bwraps2 is the same as bwraps. m_BadVariationNames.push_back(make_pair(make_pair(string("bwraps2"), string("bwraps")), badParams));//bwraps2 is the same as bwraps.
badParams.clear(); badParams.clear();
badParams.push_back("pre_bwraps2_cellsize"); badParams.push_back("pre_bwraps2_cellsize");
badParams.push_back("pre_bwraps2_space"); badParams.push_back("pre_bwraps2_space");
badParams.push_back("pre_bwraps2_gain"); badParams.push_back("pre_bwraps2_gain");
@ -232,7 +223,6 @@ public:
badParams.push_back("pre_bwraps2_outer_twist"); badParams.push_back("pre_bwraps2_outer_twist");
m_BadVariationNames.push_back(make_pair(make_pair(string("pre_bwraps2"), string("pre_bwraps")), badParams)); m_BadVariationNames.push_back(make_pair(make_pair(string("pre_bwraps2"), string("pre_bwraps")), badParams));
badParams.clear(); badParams.clear();
badParams.push_back("post_bwraps2_cellsize"); badParams.push_back("post_bwraps2_cellsize");
badParams.push_back("post_bwraps2_space"); badParams.push_back("post_bwraps2_space");
badParams.push_back("post_bwraps2_gain"); badParams.push_back("post_bwraps2_gain");
@ -240,7 +230,6 @@ public:
badParams.push_back("post_bwraps2_outer_twist"); badParams.push_back("post_bwraps2_outer_twist");
m_BadVariationNames.push_back(make_pair(make_pair(string("post_bwraps2"), string("post_bwraps")), badParams)); m_BadVariationNames.push_back(make_pair(make_pair(string("post_bwraps2"), string("post_bwraps")), badParams));
badParams.clear(); badParams.clear();
badParams.push_back("mobius_radius"); badParams.push_back("mobius_radius");
badParams.push_back("mobius_width"); badParams.push_back("mobius_width");
badParams.push_back("mobius_rect_x"); badParams.push_back("mobius_rect_x");
@ -249,7 +238,6 @@ public:
badParams.push_back("mobius_rotate_y"); badParams.push_back("mobius_rotate_y");
m_BadVariationNames.push_back(make_pair(make_pair(string("mobius"), string("mobius_strip")), badParams));//mobius_strip clashes with Mobius. m_BadVariationNames.push_back(make_pair(make_pair(string("mobius"), string("mobius_strip")), badParams));//mobius_strip clashes with Mobius.
badParams.clear(); badParams.clear();
badParams.push_back("post_dcztransl_x0"); badParams.push_back("post_dcztransl_x0");
badParams.push_back("post_dcztransl_x1"); badParams.push_back("post_dcztransl_x1");
badParams.push_back("post_dcztransl_factor"); badParams.push_back("post_dcztransl_factor");
@ -257,11 +245,9 @@ public:
badParams.push_back("post_dcztransl_clamp"); badParams.push_back("post_dcztransl_clamp");
m_BadVariationNames.push_back(make_pair(make_pair(string("post_dcztransl"), string("post_dc_ztransl")), badParams)); m_BadVariationNames.push_back(make_pair(make_pair(string("post_dcztransl"), string("post_dc_ztransl")), badParams));
badParams.clear(); badParams.clear();
m_BadVariationNames.push_back(make_pair(make_pair(string("pre_blur"), string("pre_gaussian_blur")), badParams));//No other special params for these. m_BadVariationNames.push_back(make_pair(make_pair(string("pre_blur"), string("pre_gaussian_blur")), badParams));//No other special params for these.
m_BadVariationNames.push_back(make_pair(make_pair(string("pre_spin_z"), string("pre_rotate_z")), badParams)); m_BadVariationNames.push_back(make_pair(make_pair(string("pre_spin_z"), string("pre_rotate_z")), badParams));
m_BadVariationNames.push_back(make_pair(make_pair(string("post_spin_z"), string("post_rotate_z")), badParams)); m_BadVariationNames.push_back(make_pair(make_pair(string("post_spin_z"), string("post_rotate_z")), badParams));
m_Init = true; m_Init = true;
} }
} }
@ -286,7 +272,6 @@ public:
Locale locale;//Sets and restores on exit. Locale locale;//Sets and restores on exit.
//Timing t; //Timing t;
ClearErrorReport(); ClearErrorReport();
//Parse XML string into internal document. //Parse XML string into internal document.
xmlPtr = CX(&buf[0]); xmlPtr = CX(&buf[0]);
bufSize = strlen(xmlPtr); bufSize = strlen(xmlPtr);
@ -302,7 +287,6 @@ public:
//What is the root node of the document? //What is the root node of the document?
rootnode = xmlDocGetRootElement(doc); rootnode = xmlDocGetRootElement(doc);
//Scan for <flame> nodes, starting with this node. //Scan for <flame> nodes, starting with this node.
//t.Tic(); //t.Tic();
bn = basename(const_cast<char*>(filename)); bn = basename(const_cast<char*>(filename));
@ -316,16 +300,16 @@ public:
//and should be reset to linear (with a warning). //and should be reset to linear (with a warning).
if (emberSize > 0) if (emberSize > 0)
{ {
if (embers[0].m_Interp == EMBER_INTERP_SMOOTH) if (embers[0].m_Interp == eInterp::EMBER_INTERP_SMOOTH)
{ {
cout << "Warning: smooth interpolation cannot be used for first segment.\n switching to linear.\n" << endl; cout << "Warning: smooth interpolation cannot be used for first segment.\n switching to linear.\n" << endl;
embers[0].m_Interp = EMBER_INTERP_LINEAR; embers[0].m_Interp = eInterp::EMBER_INTERP_LINEAR;
} }
if (emberSize >= 2 && embers[emberSize - 2].m_Interp == EMBER_INTERP_SMOOTH) if (emberSize >= 2 && embers[emberSize - 2].m_Interp == eInterp::EMBER_INTERP_SMOOTH)
{ {
cout << "Warning: smooth interpolation cannot be used for last segment.\n switching to linear.\n" << endl; cout << "Warning: smooth interpolation cannot be used for last segment.\n switching to linear.\n" << endl;
embers[emberSize - 2].m_Interp = EMBER_INTERP_LINEAR; embers[emberSize - 2].m_Interp = eInterp::EMBER_INTERP_LINEAR;
} }
} }
@ -336,8 +320,8 @@ public:
{ {
for (size_t i = 1; i < emberSize; i++) for (size_t i = 1; i < emberSize; i++)
{ {
//Only do this adjustment if not in compat mode.. //Only do this adjustment if not in compat mode.
if (embers[i - 1].m_AffineInterp != AFFINE_INTERP_COMPAT && embers[i - 1].m_AffineInterp != AFFINE_INTERP_OLDER) if (embers[i - 1].m_AffineInterp != eAffineInterp::AFFINE_INTERP_COMPAT && embers[i - 1].m_AffineInterp != eAffineInterp::AFFINE_INTERP_OLDER)
{ {
while (embers[i].m_Rotate < embers[i - 1].m_Rotate - 180) while (embers[i].m_Rotate < embers[i - 1].m_Rotate - 180)
embers[i].m_Rotate += 360; embers[i].m_Rotate += 360;
@ -393,7 +377,6 @@ public:
bool b = true; bool b = true;
const char* loc = __FUNCTION__; const char* loc = __FUNCTION__;
std::istringstream istr(str); std::istringstream istr(str);
istr >> val; istr >> val;
if (istr.bad() || istr.fail()) if (istr.bad() || istr.fail())
@ -416,7 +399,6 @@ public:
static string Itos(int i, int radix = 10) static string Itos(int i, int radix = 10)
{ {
char ch[16]; char ch[16];
#ifdef WIN32 #ifdef WIN32
_itoa_s(i, ch, 16, radix); _itoa_s(i, ch, 16, radix);
#else #else
@ -435,7 +417,6 @@ public:
static string Itos64(size_t i, int radix = 10) static string Itos64(size_t i, int radix = 10)
{ {
char ch[64]; char ch[64];
#ifdef WIN32 #ifdef WIN32
_ui64toa_s(i, ch, 64, radix); _ui64toa_s(i, ch, 64, radix);
#else #else
@ -493,7 +474,6 @@ private:
//if (!Interpolater<T>::InterpMissingColors(currentEmber.m_Palette.m_Entries)) //if (!Interpolater<T>::InterpMissingColors(currentEmber.m_Palette.m_Entries))
// AddToReport(string(loc) + " : Error interpolating missing palette colors"); // AddToReport(string(loc) + " : Error interpolating missing palette colors");
currentEmber.CacheXforms(); currentEmber.CacheXforms();
currentEmber.m_Index = embers.size(); currentEmber.m_Index = embers.size();
currentEmber.m_ParentFilename = parentFileString; currentEmber.m_ParentFilename = parentFileString;
@ -525,7 +505,6 @@ private:
double vals[16]; double vals[16];
xmlAttrPtr att, curAtt; xmlAttrPtr att, curAtt;
xmlNodePtr editNode, childNode, motionNode; xmlNodePtr editNode, childNode, motionNode;
currentEmber.m_Palette.Clear();//Wipe out the current palette. currentEmber.m_Palette.Clear();//Wipe out the current palette.
att = emberNode->properties;//The top level element is a ember element, read the attributes of it and store them. att = emberNode->properties;//The top level element is a ember element, read the attributes of it and store them.
@ -562,7 +541,6 @@ private:
else if (ParseAndAssign(curAtt->name, attStr, "cam_yaw", currentEmber.m_CamYaw, ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "cam_yaw", currentEmber.m_CamYaw, ret)) { }
else if (ParseAndAssign(curAtt->name, attStr, "cam_pitch", currentEmber.m_CamPitch, ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "cam_pitch", currentEmber.m_CamPitch, ret)) { }
else if (ParseAndAssign(curAtt->name, attStr, "cam_dof", currentEmber.m_CamDepthBlur, ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "cam_dof", currentEmber.m_CamDepthBlur, ret)) { }
//Parse simple int reads. //Parse simple int reads.
else if (ParseAndAssign(curAtt->name, attStr, "palette", currentEmber.m_Palette.m_Index, ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "palette", currentEmber.m_Palette.m_Index, ret)) { }
else if (ParseAndAssign(curAtt->name, attStr, "oversample", currentEmber.m_Supersample , ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "oversample", currentEmber.m_Supersample , ret)) { }
@ -572,36 +550,35 @@ private:
else if (ParseAndAssign(curAtt->name, attStr, "fuse", currentEmber.m_FuseCount , ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "fuse", currentEmber.m_FuseCount , ret)) { }
else if (ParseAndAssign(curAtt->name, attStr, "soloxform", soloXform , ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "soloxform", soloXform , ret)) { }
else if (ParseAndAssign(curAtt->name, attStr, "new_linear", newLinear , ret)) { } else if (ParseAndAssign(curAtt->name, attStr, "new_linear", newLinear , ret)) { }
//Parse more complicated reads that have multiple possible values. //Parse more complicated reads that have multiple possible values.
else if (!Compare(curAtt->name, "interpolation")) else if (!Compare(curAtt->name, "interpolation"))
{ {
if (!_stricmp("linear", attStr)) if (!_stricmp("linear", attStr))
currentEmber.m_Interp = EMBER_INTERP_LINEAR; currentEmber.m_Interp = eInterp::EMBER_INTERP_LINEAR;
else if (!_stricmp("smooth", attStr)) else if (!_stricmp("smooth", attStr))
currentEmber.m_Interp = EMBER_INTERP_SMOOTH; currentEmber.m_Interp = eInterp::EMBER_INTERP_SMOOTH;
else else
AddToReport(string(loc) + " : Unrecognized interpolation type " + string(attStr)); AddToReport(string(loc) + " : Unrecognized interpolation type " + string(attStr));
} }
else if (!Compare(curAtt->name, "palette_interpolation")) else if (!Compare(curAtt->name, "palette_interpolation"))
{ {
if (!_stricmp("hsv", attStr)) if (!_stricmp("hsv", attStr))
currentEmber.m_PaletteInterp = INTERP_HSV; currentEmber.m_PaletteInterp = ePaletteInterp::INTERP_HSV;
else if (!_stricmp("sweep", attStr)) else if (!_stricmp("sweep", attStr))
currentEmber.m_PaletteInterp = INTERP_SWEEP; currentEmber.m_PaletteInterp = ePaletteInterp::INTERP_SWEEP;
else else
AddToReport(string(loc) + " : Unrecognized palette interpolation type " + string(attStr)); AddToReport(string(loc) + " : Unrecognized palette interpolation type " + string(attStr));
} }
else if (!Compare(curAtt->name, "interpolation_space") || !Compare(curAtt->name, "interpolation_type")) else if (!Compare(curAtt->name, "interpolation_space") || !Compare(curAtt->name, "interpolation_type"))
{ {
if (!_stricmp("linear", attStr)) if (!_stricmp("linear", attStr))
currentEmber.m_AffineInterp = AFFINE_INTERP_LINEAR; currentEmber.m_AffineInterp = eAffineInterp::AFFINE_INTERP_LINEAR;
else if (!_stricmp("log", attStr)) else if (!_stricmp("log", attStr))
currentEmber.m_AffineInterp = AFFINE_INTERP_LOG; currentEmber.m_AffineInterp = eAffineInterp::AFFINE_INTERP_LOG;
else if (!_stricmp("old", attStr)) else if (!_stricmp("old", attStr))
currentEmber.m_AffineInterp = AFFINE_INTERP_COMPAT; currentEmber.m_AffineInterp = eAffineInterp::AFFINE_INTERP_COMPAT;
else if (!_stricmp("older", attStr)) else if (!_stricmp("older", attStr))
currentEmber.m_AffineInterp = AFFINE_INTERP_OLDER; currentEmber.m_AffineInterp = eAffineInterp::AFFINE_INTERP_OLDER;
else else
AddToReport(string(loc) + " : Unrecognized interpolation type " + string(attStr)); AddToReport(string(loc) + " : Unrecognized interpolation type " + string(attStr));
} }
@ -621,7 +598,6 @@ private:
{ {
AddToReport(string(loc) + " : Invalid size attribute " + string(attStr)); AddToReport(string(loc) + " : Invalid size attribute " + string(attStr));
xmlFree(attStr); xmlFree(attStr);
//These return statements are bad. One because they are inconsistent with others that just assign defaults. //These return statements are bad. One because they are inconsistent with others that just assign defaults.
//Two, because assigning easily guessable defaults is easy and less drastic. //Two, because assigning easily guessable defaults is easy and less drastic.
return false; return false;
@ -653,12 +629,12 @@ private:
else if (!Compare(curAtt->name, "palette_mode")) else if (!Compare(curAtt->name, "palette_mode"))
{ {
if (!_stricmp("step", attStr)) if (!_stricmp("step", attStr))
currentEmber.m_PaletteMode = PALETTE_STEP; currentEmber.m_PaletteMode = ePaletteMode::PALETTE_STEP;
else if (!_stricmp("linear", attStr)) else if (!_stricmp("linear", attStr))
currentEmber.m_PaletteMode = PALETTE_LINEAR; currentEmber.m_PaletteMode = ePaletteMode::PALETTE_LINEAR;
else else
{ {
currentEmber.m_PaletteMode = PALETTE_STEP; currentEmber.m_PaletteMode = ePaletteMode::PALETTE_STEP;
AddToReport(string(loc) + " : Unrecognized palette mode " + string(attStr) + ", using step"); AddToReport(string(loc) + " : Unrecognized palette mode " + string(attStr) + ", using step");
} }
} }
@ -700,7 +676,6 @@ private:
{ {
index = -1; index = -1;
double r = 0, g = 0, b = 0, a = 0; double r = 0, g = 0, b = 0, a = 0;
//Loop through the attributes of the color element. //Loop through the attributes of the color element.
att = childNode->properties; att = childNode->properties;
@ -714,7 +689,6 @@ private:
{ {
attStr = reinterpret_cast<char*>(xmlGetProp(childNode, curAtt->name)); attStr = reinterpret_cast<char*>(xmlGetProp(childNode, curAtt->name));
a = 255; a = 255;
//This signifies that a palette is not being retrieved from the palette file, rather it's being parsed directly out of the ember xml. //This signifies that a palette is not being retrieved from the palette file, rather it's being parsed directly out of the ember xml.
//This also means the palette has already been hue adjusted and it doesn't need to be done again, which would be necessary if it were //This also means the palette has already been hue adjusted and it doesn't need to be done again, which would be necessary if it were
//coming from the palette file. //coming from the palette file.
@ -724,17 +698,17 @@ private:
{ {
Aton(attStr, index); Aton(attStr, index);
} }
else if(!Compare(curAtt->name, "rgb")) else if (!Compare(curAtt->name, "rgb"))
{ {
if (sscanf_s(attStr, "%lf %lf %lf", &r, &g, &b) != 3) if (sscanf_s(attStr, "%lf %lf %lf", &r, &g, &b) != 3)
AddToReport(string(loc) + " : Invalid rgb attribute " + string(attStr)); AddToReport(string(loc) + " : Invalid rgb attribute " + string(attStr));
} }
else if(!Compare(curAtt->name, "rgba")) else if (!Compare(curAtt->name, "rgba"))
{ {
if (sscanf_s(attStr, "%lf %lf %lf %lf", &r, &g, &b, &a) != 4) if (sscanf_s(attStr, "%lf %lf %lf %lf", &r, &g, &b, &a) != 4)
AddToReport(string(loc) + " : Invalid rgba attribute " + string(attStr)); AddToReport(string(loc) + " : Invalid rgba attribute " + string(attStr));
} }
else if(!Compare(curAtt->name, "a")) else if (!Compare(curAtt->name, "a"))
{ {
if (sscanf_s(attStr, "%lf", &a) != 1) if (sscanf_s(attStr, "%lf", &a) != 1)
AddToReport(string(loc) + " : Invalid a attribute " + string(attStr)); AddToReport(string(loc) + " : Invalid a attribute " + string(attStr));
@ -751,7 +725,6 @@ private:
if (index >= 0 && index <= 255) if (index >= 0 && index <= 255)
{ {
T alphaPercent = T(a) / T(255);//Aplha percentage in the range of 0 to 1. T alphaPercent = T(a) / T(255);//Aplha percentage in the range of 0 to 1.
//Premultiply the palette. //Premultiply the palette.
currentEmber.m_Palette.m_Entries[index].r = alphaPercent * (T(r) / T(255)); currentEmber.m_Palette.m_Entries[index].r = alphaPercent * (T(r) / T(255));
currentEmber.m_Palette.m_Entries[index].g = alphaPercent * (T(g) / T(255)); currentEmber.m_Palette.m_Entries[index].g = alphaPercent * (T(g) / T(255));
@ -805,7 +778,6 @@ private:
//Make sure BOTH are not specified, otherwise either are ok. //Make sure BOTH are not specified, otherwise either are ok.
int numColors = 0; int numColors = 0;
int numBytes = 0; int numBytes = 0;
//Loop through the attributes of the palette element. //Loop through the attributes of the palette element.
att = childNode->properties; att = childNode->properties;
@ -857,7 +829,6 @@ private:
else if (!Compare(childNode->name, "symmetry")) else if (!Compare(childNode->name, "symmetry"))
{ {
int symKind = INT_MAX; int symKind = INT_MAX;
//Loop through the attributes of the palette element. //Loop through the attributes of the palette element.
att = childNode->properties; att = childNode->properties;
@ -961,7 +932,6 @@ private:
else if (!Compare(childNode->name, "flame_motion")) else if (!Compare(childNode->name, "flame_motion"))
{ {
EmberMotion<T> motion; EmberMotion<T> motion;
att = childNode->properties; att = childNode->properties;
if (att == nullptr) if (att == nullptr)
@ -981,13 +951,13 @@ private:
string func(attStr); string func(attStr);
if (func == "sin") if (func == "sin")
motion.m_MotionFunc = MOTION_SIN; motion.m_MotionFunc = eMotion::MOTION_SIN;
else if (func == "triangle") else if (func == "triangle")
motion.m_MotionFunc = MOTION_TRIANGLE; motion.m_MotionFunc = eMotion::MOTION_TRIANGLE;
else if (func == "hill") else if (func == "hill")
motion.m_MotionFunc = MOTION_HILL; motion.m_MotionFunc = eMotion::MOTION_HILL;
else if (func == "saw") else if (func == "saw")
motion.m_MotionFunc = MOTION_SAW; motion.m_MotionFunc = eMotion::MOTION_SAW;
else else
{ {
AddToReport(string(loc) + " : invalid flame motion function " + func); AddToReport(string(loc) + " : invalid flame motion function " + func);
@ -995,29 +965,29 @@ private:
} }
} }
else if (!Compare(curAtt->name, "zoom")) else if (!Compare(curAtt->name, "zoom"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_ZOOM, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_ZOOM, motion);
else if (!Compare(curAtt->name, "cam_zpos")) else if (!Compare(curAtt->name, "cam_zpos"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_ZPOS, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_ZPOS, motion);
else if (!Compare(curAtt->name, "cam_persp")) else if (!Compare(curAtt->name, "cam_persp"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_PERSPECTIVE, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_PERSPECTIVE, motion);
else if (!Compare(curAtt->name, "cam_yaw")) else if (!Compare(curAtt->name, "cam_yaw"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_YAW, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_YAW, motion);
else if (!Compare(curAtt->name, "cam_pitch")) else if (!Compare(curAtt->name, "cam_pitch"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_PITCH, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_PITCH, motion);
else if (!Compare(curAtt->name, "cam_dof")) else if (!Compare(curAtt->name, "cam_dof"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_DEPTH_BLUR, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_DEPTH_BLUR, motion);
else if (!Compare(curAtt->name, "rotate")) else if (!Compare(curAtt->name, "rotate"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_ROTATE, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_ROTATE, motion);
else if (!Compare(curAtt->name, "brightness")) else if (!Compare(curAtt->name, "brightness"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_BRIGHTNESS, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_BRIGHTNESS, motion);
else if (!Compare(curAtt->name, "gamma")) else if (!Compare(curAtt->name, "gamma"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_GAMMA, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_GAMMA, motion);
else if (!Compare(curAtt->name, "gamma_threshold")) else if (!Compare(curAtt->name, "gamma_threshold"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_GAMMA_THRESH, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_GAMMA_THRESH, motion);
else if (!Compare(curAtt->name, "highlight_power")) else if (!Compare(curAtt->name, "highlight_power"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_HIGHLIGHT_POWER, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_HIGHLIGHT_POWER, motion);
else if (!Compare(curAtt->name, "vibrancy")) else if (!Compare(curAtt->name, "vibrancy"))
ret = ret && AttToEmberMotionFloat(att, attStr, FLAME_MOTION_VIBRANCY, motion); ret = ret && AttToEmberMotionFloat(att, attStr, eEmberMotionParam::FLAME_MOTION_VIBRANCY, motion);
else if (!Compare(curAtt->name, "background")) else if (!Compare(curAtt->name, "background"))
{ {
double r, g, b; double r, g, b;
@ -1030,13 +1000,13 @@ private:
} }
if (r != 0) if (r != 0)
motion.m_MotionParams.push_back(MotionParam<T>(FLAME_MOTION_BACKGROUND_R, T(r))); motion.m_MotionParams.push_back(MotionParam<T>(eEmberMotionParam::FLAME_MOTION_BACKGROUND_R, T(r)));
if (g != 0) if (g != 0)
motion.m_MotionParams.push_back(MotionParam<T>(FLAME_MOTION_BACKGROUND_G, T(g))); motion.m_MotionParams.push_back(MotionParam<T>(eEmberMotionParam::FLAME_MOTION_BACKGROUND_G, T(g)));
if (b != 0) if (b != 0)
motion.m_MotionParams.push_back(MotionParam<T>(FLAME_MOTION_BACKGROUND_B, T(b))); motion.m_MotionParams.push_back(MotionParam<T>(eEmberMotionParam::FLAME_MOTION_BACKGROUND_B, T(b)));
} }
else if (!Compare(curAtt->name, "center")) else if (!Compare(curAtt->name, "center"))
{ {
@ -1050,10 +1020,10 @@ private:
} }
if (cx != 0) if (cx != 0)
motion.m_MotionParams.push_back(MotionParam<T>(FLAME_MOTION_CENTER_X, T(cx))); motion.m_MotionParams.push_back(MotionParam<T>(eEmberMotionParam::FLAME_MOTION_CENTER_X, T(cx)));
if (cy != 0) if (cy != 0)
motion.m_MotionParams.push_back(MotionParam<T>(FLAME_MOTION_CENTER_Y, T(cy))); motion.m_MotionParams.push_back(MotionParam<T>(eEmberMotionParam::FLAME_MOTION_CENTER_Y, T(cy)));
} }
else else
{ {
@ -1123,7 +1093,6 @@ private:
double a, b, c, d, e, f; double a, b, c, d, e, f;
double vals[10]; double vals[10];
xmlAttrPtr attPtr, curAtt; xmlAttrPtr attPtr, curAtt;
//Loop through the attributes of the xform element. //Loop through the attributes of the xform element.
attPtr = childNode->properties; attPtr = childNode->properties;
@ -1145,7 +1114,6 @@ private:
else if (ParseAndAssign(curAtt->name, attStr, "var_color", xform.m_DirectColor, success)) { } else if (ParseAndAssign(curAtt->name, attStr, "var_color", xform.m_DirectColor, success)) { }
else if (ParseAndAssign(curAtt->name, attStr, "motion_frequency", xform.m_MotionFreq, success)) { } else if (ParseAndAssign(curAtt->name, attStr, "motion_frequency", xform.m_MotionFreq, success)) { }
else if (ParseAndAssign(curAtt->name, attStr, "motion_offset", xform.m_MotionOffset, success)) { } else if (ParseAndAssign(curAtt->name, attStr, "motion_offset", xform.m_MotionOffset, success)) { }
//Parse more complicated reads that have multiple possible values. //Parse more complicated reads that have multiple possible values.
else if (!Compare(curAtt->name, "name")) else if (!Compare(curAtt->name, "name"))
{ {
@ -1163,16 +1131,16 @@ private:
else if (!Compare(curAtt->name, "motion_function")) else if (!Compare(curAtt->name, "motion_function"))
{ {
if (!_stricmp("sin", attStr)) if (!_stricmp("sin", attStr))
xform.m_MotionFunc = MOTION_SIN; xform.m_MotionFunc = eMotion::MOTION_SIN;
else if (!_stricmp("triangle", attStr)) else if (!_stricmp("triangle", attStr))
xform.m_MotionFunc = MOTION_TRIANGLE; xform.m_MotionFunc = eMotion::MOTION_TRIANGLE;
else if (!_stricmp("hill", attStr)) else if (!_stricmp("hill", attStr))
xform.m_MotionFunc = MOTION_HILL; xform.m_MotionFunc = eMotion::MOTION_HILL;
else if (!_stricmp("saw", attStr)) else if (!_stricmp("saw", attStr))
xform.m_MotionFunc = MOTION_SAW; xform.m_MotionFunc = eMotion::MOTION_SAW;
else else
{ {
xform.m_MotionFunc = MOTION_SIN; xform.m_MotionFunc = eMotion::MOTION_SIN;
AddToReport(string(loc) + " : Unknown motion function " + string(attStr) + ", using sin"); AddToReport(string(loc) + " : Unknown motion function " + string(attStr) + ", using sin");
} }
} }
@ -1254,10 +1222,10 @@ private:
if (auto var = m_VariationList.GetVariation(s)) if (auto var = m_VariationList.GetVariation(s))
{ {
auto varCopy = var->Copy(); auto varCopy = var->Copy();
Aton(attStr, varCopy->m_Weight); Aton(attStr, varCopy->m_Weight);
xform.AddVariation(varCopy); xform.AddVariation(varCopy);
} }
//else //else
//{ //{
// AddToReport("Unsupported variation: " + string((const char*)curAtt->name)); // AddToReport("Unsupported variation: " + string((const char*)curAtt->name));
@ -1421,7 +1389,8 @@ private:
{ {
if (!_stricmp(name, CCX(temp->name))) if (!_stricmp(name, CCX(temp->name)))
return true; return true;
} while ((temp = temp->next)); }
while ((temp = temp->next));
return false; return false;
} }
@ -1454,11 +1423,11 @@ private:
{ {
//Parse an RGB triplet at a time. //Parse an RGB triplet at a time.
if (chan == 3) if (chan == 3)
ret = sscanf_s(&(colstr[colorIndex]),"%2x%2x%2x", &r, &g, &b); ret = sscanf_s(&(colstr[colorIndex]), "%2x%2x%2x", &r, &g, &b);
else if (chan == -4) else if (chan == -4)
ret = sscanf_s(&(colstr[colorIndex]),"00%2x%2x%2x", &r, &g, &b); ret = sscanf_s(&(colstr[colorIndex]), "00%2x%2x%2x", &r, &g, &b);
else // chan==4 else // chan==4
ret = sscanf_s(&(colstr[colorIndex]),"%2x%2x%2x%2x", &r,&g, &b, &a); ret = sscanf_s(&(colstr[colorIndex]), "%2x%2x%2x%2x", &r, &g, &b, &a);
a = 1;//Original allows for alpha, even though it will most likely never happen. Ember omits support for it. a = 1;//Original allows for alpha, even though it will most likely never happen. Ember omits support for it.
@ -1479,15 +1448,15 @@ private:
ember.m_Palette.m_Entries[colorCount].g = T(g) / T(255); ember.m_Palette.m_Entries[colorCount].g = T(g) / T(255);
ember.m_Palette.m_Entries[colorCount].b = T(b) / T(255); ember.m_Palette.m_Entries[colorCount].b = T(b) / T(255);
ember.m_Palette.m_Entries[colorCount].a = T(a); ember.m_Palette.m_Entries[colorCount].a = T(a);
colorCount++; colorCount++;
}
} while (colorCount < numColors && colorCount < ember.m_Palette.m_Entries.size()); while (colorCount < numColors && colorCount < ember.m_Palette.m_Entries.size());
#ifdef WIN32 #ifdef WIN32
if (sscanf_s(&(colstr[colorIndex]),"%1s", tmps, sizeof(tmps)) > 0)//Really need to migrate all of this parsing to C++.//TODO
if (sscanf_s(&(colstr[colorIndex]), "%1s", tmps, sizeof(tmps)) > 0) //Really need to migrate all of this parsing to C++.//TODO
#else #else
if (sscanf_s(&(colstr[colorIndex]),"%1s", tmps) > 0) if (sscanf_s(&(colstr[colorIndex]), "%1s", tmps) > 0)
#endif #endif
{ {
AddToReport(string(loc) + " : Extra data at end of hex color data " + string(&(colstr[colorIndex]))); AddToReport(string(loc) + " : Extra data at end of hex color data " + string(&(colstr[colorIndex])));
@ -1514,7 +1483,6 @@ private:
if (!Compare(name, str)) if (!Compare(name, str))
{ {
istringstream istr(attStr); istringstream istr(attStr);
istr >> val; istr >> val;
ret = !istr.bad() && !istr.fail();//Means the Compare() was right, and the conversion succeeded. ret = !istr.bad() && !istr.fail();//Means the Compare() was right, and the conversion succeeded.
} }

View File

@ -354,7 +354,7 @@ bool EmberAnimate(EmberOptions& opt)
renderer->Reset(); renderer->Reset();
if ((renderer->Run(finalImages[finalImageIndex], localTime) != RENDER_OK) || renderer->Aborted() || finalImages[finalImageIndex].empty()) if ((renderer->Run(finalImages[finalImageIndex], localTime) != eRenderStatus::RENDER_OK) || renderer->Aborted() || finalImages[finalImageIndex].empty())
{ {
cout << "Error: image rendering failed, skipping to next image." << endl; cout << "Error: image rendering failed, skipping to next image." << endl;
renderer->DumpErrorReport();//Something went wrong, print errors. renderer->DumpErrorReport();//Something went wrong, print errors.

View File

@ -455,7 +455,7 @@ string IterOpenCLKernelCreator<T>::CreateIterKernelString(const Ember<T>& ember,
//Basic texture index interoplation does not produce identical results //Basic texture index interoplation does not produce identical results
//to the CPU. So the code here must explicitly do the same thing and not //to the CPU. So the code here must explicitly do the same thing and not
//rely on the GPU texture coordinate lookup. //rely on the GPU texture coordinate lookup.
if (ember.m_PaletteMode == PALETTE_LINEAR) if (ember.m_PaletteMode == ePaletteMode::PALETTE_LINEAR)
{ {
os << os <<
" real_t colorIndexFrac;\n" " real_t colorIndexFrac;\n"
@ -484,7 +484,7 @@ string IterOpenCLKernelCreator<T>::CreateIterKernelString(const Ember<T>& ember,
" palColor2 = read_imagef(palette, paletteSampler, iPaletteCoord);\n" " palColor2 = read_imagef(palette, paletteSampler, iPaletteCoord);\n"
" palColor1 = (palColor1 * (1.0f - (float)colorIndexFrac)) + (palColor2 * (float)colorIndexFrac);\n";//The 1.0f here *must* have the 'f' suffix at the end to compile. " palColor1 = (palColor1 * (1.0f - (float)colorIndexFrac)) + (palColor2 * (float)colorIndexFrac);\n";//The 1.0f here *must* have the 'f' suffix at the end to compile.
} }
else if (ember.m_PaletteMode == PALETTE_STEP) else if (ember.m_PaletteMode == ePaletteMode::PALETTE_STEP)
{ {
os << os <<
" iPaletteCoord.x = (int)(secondPoint.m_ColorX * COLORMAP_LENGTH);\n" " iPaletteCoord.x = (int)(secondPoint.m_ColorX * COLORMAP_LENGTH);\n"
@ -922,9 +922,9 @@ string IterOpenCLKernelCreator<T>::CreateProjectionString(const Ember<T>& ember)
if (projBits) if (projBits)
{ {
if (projBits & PROJBITS_BLUR) if (projBits & size_t(eProjBits::PROJBITS_BLUR))
{ {
if (projBits & PROJBITS_YAW) if (projBits & size_t(eProjBits::PROJBITS_YAW))
{ {
os << os <<
" real_t dsin, dcos;\n" " real_t dsin, dcos;\n"
@ -967,9 +967,9 @@ string IterOpenCLKernelCreator<T>::CreateProjectionString(const Ember<T>& ember)
" secondPoint.m_Z -= ember->m_CamZPos;\n"; " secondPoint.m_Z -= ember->m_CamZPos;\n";
} }
} }
else if ((projBits & PROJBITS_PITCH) || (projBits & PROJBITS_YAW)) else if ((projBits & size_t(eProjBits::PROJBITS_PITCH)) || (projBits & size_t(eProjBits::PROJBITS_YAW)))
{ {
if (projBits & PROJBITS_YAW) if (projBits & size_t(eProjBits::PROJBITS_YAW))
{ {
os << os <<
" real_t z = secondPoint.m_Z - ember->m_CamZPos;\n" " real_t z = secondPoint.m_Z - ember->m_CamZPos;\n"

View File

@ -769,14 +769,14 @@ eRenderStatus RendererCL<T, bucketT>::GaussianDensityFilter()
template <typename T, typename bucketT> template <typename T, typename bucketT>
eRenderStatus RendererCL<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t finalOffset) eRenderStatus RendererCL<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t finalOffset)
{ {
eRenderStatus status = RunFinalAccum(); auto status = RunFinalAccum();
if (status == RENDER_OK && pixels && !m_Devices.empty() && !m_Devices[0]->m_Wrapper.Shared()) if (status == eRenderStatus::RENDER_OK && pixels && !m_Devices.empty() && !m_Devices[0]->m_Wrapper.Shared())
{ {
pixels += finalOffset; pixels += finalOffset;
if (!ReadFinal(pixels)) if (!ReadFinal(pixels))
status = RENDER_ERROR; status = eRenderStatus::RENDER_ERROR;
} }
return status; return status;
@ -853,7 +853,7 @@ EmberStats RendererCL<T, bucketT>::Iterate(size_t iterCount, size_t temporalSamp
{ {
m_IterTimer.Tic();//Tic() here to avoid including build time in iter time measurement. m_IterTimer.Tic();//Tic() here to avoid including build time in iter time measurement.
if (m_LastIter == 0 && m_ProcessAction != KEEP_ITERATING)//Only reset the call count on the beginning of a new render. Do not reset on KEEP_ITERATING. if (m_LastIter == 0 && m_ProcessAction != eProcessAction::KEEP_ITERATING)//Only reset the call count on the beginning of a new render. Do not reset on KEEP_ITERATING.
for (auto& dev : m_Devices) for (auto& dev : m_Devices)
dev->m_Calls = 0; dev->m_Calls = 0;
@ -1166,7 +1166,7 @@ eRenderStatus RendererCL<T, bucketT>::RunLogScaleFilter()
m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 1, 0.0); m_Callback->ProgressFunc(m_Ember, m_ProgressParameter, 100.0, 1, 0.0);
} }
return b ? RENDER_OK : RENDER_ERROR; return b ? eRenderStatus::RENDER_OK : eRenderStatus::RENDER_ERROR;
} }
/// <summary> /// <summary>
@ -1288,7 +1288,7 @@ eRenderStatus RendererCL<T, bucketT>::RunDensityFilter()
AddToReport(loc); AddToReport(loc);
} }
return m_Abort ? RENDER_ABORT : (b ? RENDER_OK : RENDER_ERROR); return m_Abort ? eRenderStatus::RENDER_ABORT : (b ? eRenderStatus::RENDER_OK : eRenderStatus::RENDER_ERROR);
} }
/// <summary> /// <summary>
@ -1389,7 +1389,7 @@ eRenderStatus RendererCL<T, bucketT>::RunFinalAccum()
AddToReport(loc); AddToReport(loc);
} }
return b ? RENDER_OK : RENDER_ERROR; return b ? eRenderStatus::RENDER_OK : eRenderStatus::RENDER_ERROR;
} }
/// <summary> /// <summary>

View File

@ -441,7 +441,7 @@ static bool StripsRender(RendererBase* renderer, Ember<T>& ember, vector<byte>&
renderer->SetEmber(ember);//Set one final time after modifications for strips. renderer->SetEmber(ember);//Set one final time after modifications for strips.
} }
if ((renderer->Run(finalImage, time, 0, false, stripOffset) == RENDER_OK) && !renderer->Aborted() && !finalImage.empty()) if ((renderer->Run(finalImage, time, 0, false, stripOffset) == eRenderStatus::RENDER_OK) && !renderer->Aborted() && !finalImage.empty())
{ {
perStripFinish(strip); perStripFinish(strip);
} }

View File

@ -11,8 +11,8 @@ template <typename T>
void SetDefaultTestValues(Ember<T>& ember) void SetDefaultTestValues(Ember<T>& ember)
{ {
ember.m_Time = 0.0; ember.m_Time = 0.0;
ember.m_Interp = EMBER_INTERP_LINEAR; ember.m_Interp = eInterp::EMBER_INTERP_LINEAR;
ember.m_PaletteInterp = INTERP_HSV; ember.m_PaletteInterp = ePaletteInterp::INTERP_HSV;
ember.m_Background[0] = 0; ember.m_Background[0] = 0;
ember.m_Background[1] = 0; ember.m_Background[1] = 0;
ember.m_Background[2] = 0; ember.m_Background[2] = 0;
@ -25,7 +25,7 @@ void SetDefaultTestValues(Ember<T>& ember)
ember.m_FinalRasH = 128; ember.m_FinalRasH = 128;
ember.m_Supersample = 1; ember.m_Supersample = 1;
ember.m_SpatialFilterRadius = T(0.5); ember.m_SpatialFilterRadius = T(0.5);
ember.m_SpatialFilterType = GAUSSIAN_SPATIAL_FILTER; ember.m_SpatialFilterType = eSpatialFilterType::GAUSSIAN_SPATIAL_FILTER;
ember.m_Zoom = 0; ember.m_Zoom = 0;
ember.m_Quality = 1; ember.m_Quality = 1;
ember.m_TemporalSamples = 1; ember.m_TemporalSamples = 1;
@ -353,7 +353,7 @@ bool EmberGenome(EmberOptions& opt)
} }
if (!exactTimeMatch) if (!exactTimeMatch)
interpolated.m_AffineInterp = AFFINE_INTERP_LINEAR; interpolated.m_AffineInterp = eAffineInterp::AFFINE_INTERP_LINEAR;
} }
if (pTemplate) if (pTemplate)
@ -685,7 +685,7 @@ bool EmberGenome(EmberOptions& opt)
SetDefaultTestValues(orig); SetDefaultTestValues(orig);
renderer->SetEmber(orig); renderer->SetEmber(orig);
if (renderer->Run(finalImage) != RENDER_OK) if (renderer->Run(finalImage) != eRenderStatus::RENDER_OK)
{ {
cerr << "Error: test image rendering failed, aborting." << endl; cerr << "Error: test image rendering failed, aborting." << endl;
return false; return false;

View File

@ -255,13 +255,13 @@ FinalRenderGuiState FractoriumFinalRenderDialog::State()
eScaleType FractoriumFinalRenderDialog::Scale() eScaleType FractoriumFinalRenderDialog::Scale()
{ {
if (ui.FinalRenderScaleNoneRadioButton->isChecked()) if (ui.FinalRenderScaleNoneRadioButton->isChecked())
return SCALE_NONE; return eScaleType::SCALE_NONE;
else if (ui.FinalRenderScaleWidthRadioButton->isChecked()) else if (ui.FinalRenderScaleWidthRadioButton->isChecked())
return SCALE_WIDTH; return eScaleType::SCALE_WIDTH;
else if (ui.FinalRenderScaleHeightRadioButton->isChecked()) else if (ui.FinalRenderScaleHeightRadioButton->isChecked())
return SCALE_HEIGHT; return eScaleType::SCALE_HEIGHT;
else else
return SCALE_NONE; return eScaleType::SCALE_NONE;
} }
/// <summary> /// <summary>
@ -272,11 +272,11 @@ void FractoriumFinalRenderDialog::Scale(eScaleType scale)
{ {
ui.FinalRenderScaleNoneRadioButton->blockSignals(true); ui.FinalRenderScaleNoneRadioButton->blockSignals(true);
if (scale == SCALE_NONE) if (scale == eScaleType::SCALE_NONE)
ui.FinalRenderScaleNoneRadioButton->setChecked(true); ui.FinalRenderScaleNoneRadioButton->setChecked(true);
else if (scale == SCALE_WIDTH) else if (scale == eScaleType::SCALE_WIDTH)
ui.FinalRenderScaleWidthRadioButton->setChecked(true); ui.FinalRenderScaleWidthRadioButton->setChecked(true);
else if (scale == SCALE_HEIGHT) else if (scale == eScaleType::SCALE_HEIGHT)
ui.FinalRenderScaleHeightRadioButton->setChecked(true); ui.FinalRenderScaleHeightRadioButton->setChecked(true);
else else
ui.FinalRenderScaleNoneRadioButton->setChecked(true); ui.FinalRenderScaleNoneRadioButton->setChecked(true);

View File

@ -235,7 +235,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
renderTimer.Tic();//Toc() is called in RenderComplete(). renderTimer.Tic();//Toc() is called in RenderComplete().
//Can't use strips render here. Run() must be called directly for animation. //Can't use strips render here. Run() must be called directly for animation.
if (renderer->Run(finalImages[finalImageIndex], localTime) != RENDER_OK) if (renderer->Run(finalImages[finalImageIndex], localTime) != eRenderStatus::RENDER_OK)
{ {
Output("Rendering failed.\n"); Output("Rendering failed.\n");
m_Fractorium->ErrorReportToQTextEdit(renderer->ErrorReport(), m_FinalRenderDialog->ui.FinalRenderTextOutput, false);//Internally calls invoke. m_Fractorium->ErrorReportToQTextEdit(renderer->ErrorReport(), m_FinalRenderDialog->ui.FinalRenderTextOutput, false);//Internally calls invoke.
@ -874,7 +874,7 @@ void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember, const EmberS
m_Settings->FinalDoAll(m_GuiState.m_DoAll); m_Settings->FinalDoAll(m_GuiState.m_DoAll);
m_Settings->FinalDoSequence(m_GuiState.m_DoSequence); m_Settings->FinalDoSequence(m_GuiState.m_DoSequence);
m_Settings->FinalKeepAspect(m_GuiState.m_KeepAspect); m_Settings->FinalKeepAspect(m_GuiState.m_KeepAspect);
m_Settings->FinalScale(m_GuiState.m_Scale); m_Settings->FinalScale(uint(m_GuiState.m_Scale));
m_Settings->FinalExt(m_GuiState.m_Ext); m_Settings->FinalExt(m_GuiState.m_Ext);
m_Settings->FinalThreadCount(m_GuiState.m_ThreadCount); m_Settings->FinalThreadCount(m_GuiState.m_ThreadCount);
m_Settings->FinalThreadPriority(m_GuiState.m_ThreadPriority); m_Settings->FinalThreadPriority(m_GuiState.m_ThreadPriority);

View File

@ -108,13 +108,13 @@ FractoriumEmberController<T>::FractoriumEmberController(Fractorium* fractorium)
{ {
Ember<T> ember = m_EmberFile.m_Embers[i]; Ember<T> ember = m_EmberFile.m_Embers[i];
ember.SyncSize(); ember.SyncSize();
ember.SetSizeAndAdjustScale(PREVIEW_SIZE, PREVIEW_SIZE, false, SCALE_WIDTH); ember.SetSizeAndAdjustScale(PREVIEW_SIZE, PREVIEW_SIZE, false, eScaleType::SCALE_WIDTH);
ember.m_TemporalSamples = 1; ember.m_TemporalSamples = 1;
ember.m_Quality = 25; ember.m_Quality = 25;
ember.m_Supersample = 1; ember.m_Supersample = 1;
m_PreviewRenderer->SetEmber(ember); m_PreviewRenderer->SetEmber(ember);
if (m_PreviewRenderer->Run(m_PreviewFinalImage) == RENDER_OK) if (m_PreviewRenderer->Run(m_PreviewFinalImage) == eRenderStatus::RENDER_OK)
{ {
if (EmberTreeWidgetItem<T>* treeItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i))) if (EmberTreeWidgetItem<T>* treeItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
{ {
@ -211,7 +211,7 @@ void FractoriumEmberController<T>::SetEmber(size_t index)
/// </summary> /// </summary>
/// <param name="func">The function to call</param> /// <param name="func">The function to call</param>
/// <param name="updateRender">True to update renderer, else false. Default: true.</param> /// <param name="updateRender">True to update renderer, else false. Default: true.</param>
/// <param name="action">The action to add to the rendering queue. Default: FULL_RENDER.</param> /// <param name="action">The action to add to the rendering queue. Default: eProcessAction::FULL_RENDER.</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::Update(std::function<void (void)> func, bool updateRender, eProcessAction action) void FractoriumEmberController<T>::Update(std::function<void (void)> func, bool updateRender, eProcessAction action)
{ {
@ -228,7 +228,7 @@ void FractoriumEmberController<T>::Update(std::function<void (void)> func, bool
/// <param name="func">The function to call</param> /// <param name="func">The function to call</param>
/// <param name="updateType">Whether to apply this update operation on the current, all or selected xforms. Default: UPDATE_CURRENT.</param> /// <param name="updateType">Whether to apply this update operation on the current, all or selected xforms. Default: UPDATE_CURRENT.</param>
/// <param name="updateRender">True to update renderer, else false. Default: true.</param> /// <param name="updateRender">True to update renderer, else false. Default: true.</param>
/// <param name="action">The action to add to the rendering queue. Default: FULL_RENDER.</param> /// <param name="action">The action to add to the rendering queue. Default: eProcessAction::FULL_RENDER.</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*)> func, eXformUpdate updateType, bool updateRender, eProcessAction action) void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*)> func, eXformUpdate updateType, bool updateRender, eProcessAction action)
{ {

View File

@ -219,7 +219,7 @@ public:
void StopRenderTimer(bool wait); void StopRenderTimer(bool wait);
void ClearFinalImages(); void ClearFinalImages();
void Shutdown(); void Shutdown();
void UpdateRender(eProcessAction action = FULL_RENDER); void UpdateRender(eProcessAction action = eProcessAction::FULL_RENDER);
void DeleteRenderer(); void DeleteRenderer();
void SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<byte>& pixels, size_t width, size_t height, size_t channels, size_t bpc); void SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<byte>& pixels, size_t width, size_t height, size_t channels, size_t bpc);
RendererBase* Renderer() { return m_Renderer.get(); } RendererBase* Renderer() { return m_Renderer.get(); }
@ -231,7 +231,7 @@ protected:
//Rendering/progress. //Rendering/progress.
void AddProcessAction(eProcessAction action); void AddProcessAction(eProcessAction action);
eProcessAction CondenseAndClearProcessActions(); eProcessAction CondenseAndClearProcessActions();
eProcessState ProcessState() { return m_Renderer.get() ? m_Renderer->ProcessState() : NONE; } eProcessState ProcessState() { return m_Renderer.get() ? m_Renderer->ProcessState() : eProcessState::NONE; }
//Non-templated members. //Non-templated members.
bool m_Rendering; bool m_Rendering;
@ -473,13 +473,13 @@ private:
QString MakeXformCaption(size_t i); QString MakeXformCaption(size_t i);
bool XformCheckboxAt(int i, std::function<void(QCheckBox*)> func); bool XformCheckboxAt(int i, std::function<void(QCheckBox*)> func);
bool XformCheckboxAt(Xform<T>* xform, std::function<void(QCheckBox*)> func); bool XformCheckboxAt(Xform<T>* xform, std::function<void(QCheckBox*)> func);
void UpdateXform(std::function<void(Xform<T>*)> func, eXformUpdate updateType = eXformUpdate::UPDATE_CURRENT, bool updateRender = true, eProcessAction action = FULL_RENDER); void UpdateXform(std::function<void(Xform<T>*)> func, eXformUpdate updateType = eXformUpdate::UPDATE_CURRENT, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER);
//Palette. //Palette.
void UpdateAdjustedPaletteGUI(Palette<T>& palette); void UpdateAdjustedPaletteGUI(Palette<T>& palette);
//Rendering/progress. //Rendering/progress.
void Update(std::function<void (void)> func, bool updateRender = true, eProcessAction action = FULL_RENDER); void Update(std::function<void (void)> func, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER);
bool SyncSizes(); bool SyncSizes();
//Templated members. //Templated members.

View File

@ -37,7 +37,7 @@ void Fractorium::InitParamsUI()
comboVals.push_back("Step"); comboVals.push_back("Step");
comboVals.push_back("Linear"); comboVals.push_back("Linear");
SetupCombo(table, this, row, 1, m_PaletteModeCombo, comboVals, SIGNAL(currentIndexChanged(int)), SLOT(OnPaletteModeComboCurrentIndexChanged(int))); SetupCombo(table, this, row, 1, m_PaletteModeCombo, comboVals, SIGNAL(currentIndexChanged(int)), SLOT(OnPaletteModeComboCurrentIndexChanged(int)));
m_PaletteModeCombo->SetCurrentIndexStealth(PALETTE_LINEAR); m_PaletteModeCombo->SetCurrentIndexStealth(int(ePaletteMode::PALETTE_LINEAR));
//Geometry. //Geometry.
row = 0; row = 0;
table = ui.GeometryTable; table = ui.GeometryTable;
@ -100,7 +100,7 @@ void Fractorium::InitParamsUI()
/// </summary> /// </summary>
/// <param name="d">The brightness</param> /// <param name="d">The brightness</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::BrightnessChanged(double d) { Update([&] { m_Ember.m_Brightness = d; }, true, FILTER_AND_ACCUM); } void FractoriumEmberController<T>::BrightnessChanged(double d) { Update([&] { m_Ember.m_Brightness = d; }, true, eProcessAction::FILTER_AND_ACCUM); }
void Fractorium::OnBrightnessChanged(double d) { m_Controller->BrightnessChanged(d); } void Fractorium::OnBrightnessChanged(double d) { m_Controller->BrightnessChanged(d); }
/// <summary> /// <summary>
@ -110,7 +110,7 @@ void Fractorium::OnBrightnessChanged(double d) { m_Controller->BrightnessChanged
/// else if early clip is true, filter and accum, else final accum only. /// else if early clip is true, filter and accum, else final accum only.
/// </summary> /// </summary>
/// <param name="d">The gamma value</param> /// <param name="d">The gamma value</param>
template <typename T> void FractoriumEmberController<T>::GammaChanged(double d) { Update([&] { m_Ember.m_Gamma = d; }, true, m_Ember.m_TemporalSamples > 1 ? FULL_RENDER : (m_Renderer->EarlyClip() ? FILTER_AND_ACCUM : ACCUM_ONLY)); } template <typename T> void FractoriumEmberController<T>::GammaChanged(double d) { Update([&] { m_Ember.m_Gamma = d; }, true, m_Ember.m_TemporalSamples > 1 ? eProcessAction::FULL_RENDER : (m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY)); }
void Fractorium::OnGammaChanged(double d) { m_Controller->GammaChanged(d); } void Fractorium::OnGammaChanged(double d) { m_Controller->GammaChanged(d); }
/// <summary> /// <summary>
@ -119,7 +119,7 @@ void Fractorium::OnGammaChanged(double d) { m_Controller->GammaChanged(d); }
/// Resets the rendering process to the final accumulation stage. /// Resets the rendering process to the final accumulation stage.
/// </summary> /// </summary>
/// <param name="d">The gamma threshold</param> /// <param name="d">The gamma threshold</param>
template <typename T> void FractoriumEmberController<T>::GammaThresholdChanged(double d) { Update([&] { m_Ember.m_GammaThresh = d; }, true, m_Ember.m_TemporalSamples > 1 ? FULL_RENDER : (m_Renderer->EarlyClip() ? FILTER_AND_ACCUM : ACCUM_ONLY)); } template <typename T> void FractoriumEmberController<T>::GammaThresholdChanged(double d) { Update([&] { m_Ember.m_GammaThresh = d; }, true, m_Ember.m_TemporalSamples > 1 ? eProcessAction::FULL_RENDER : (m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY)); }
void Fractorium::OnGammaThresholdChanged(double d) { m_Controller->GammaThresholdChanged(d); } void Fractorium::OnGammaThresholdChanged(double d) { m_Controller->GammaThresholdChanged(d); }
/// <summary> /// <summary>
@ -128,7 +128,7 @@ void Fractorium::OnGammaThresholdChanged(double d) { m_Controller->GammaThreshol
/// Resets the rendering process to the final accumulation stage if temporal samples is 1, else full reset. /// Resets the rendering process to the final accumulation stage if temporal samples is 1, else full reset.
/// </summary> /// </summary>
/// <param name="d">The vibrancy</param> /// <param name="d">The vibrancy</param>
template <typename T> void FractoriumEmberController<T>::VibrancyChanged(double d) { Update([&] { m_Ember.m_Vibrancy = d; }, true, m_Ember.m_TemporalSamples > 1 ? FULL_RENDER : (m_Renderer->EarlyClip() ? FILTER_AND_ACCUM : ACCUM_ONLY)); } template <typename T> void FractoriumEmberController<T>::VibrancyChanged(double d) { Update([&] { m_Ember.m_Vibrancy = d; }, true, m_Ember.m_TemporalSamples > 1 ? eProcessAction::FULL_RENDER : (m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY)); }
void Fractorium::OnVibrancyChanged(double d) { m_Controller->VibrancyChanged(d); } void Fractorium::OnVibrancyChanged(double d) { m_Controller->VibrancyChanged(d); }
/// <summary> /// <summary>
@ -137,7 +137,7 @@ void Fractorium::OnVibrancyChanged(double d) { m_Controller->VibrancyChanged(d);
/// Resets the rendering process to the final accumulation stage. /// Resets the rendering process to the final accumulation stage.
/// </summary> /// </summary>
/// <param name="d">The highlight power</param> /// <param name="d">The highlight power</param>
template <typename T> void FractoriumEmberController<T>::HighlightPowerChanged(double d) { Update([&] { m_Ember.m_HighlightPower = d; }, true, m_Ember.m_TemporalSamples > 1 ? FULL_RENDER : (m_Renderer->EarlyClip() ? FILTER_AND_ACCUM : ACCUM_ONLY)); } template <typename T> void FractoriumEmberController<T>::HighlightPowerChanged(double d) { Update([&] { m_Ember.m_HighlightPower = d; }, true, m_Ember.m_TemporalSamples > 1 ? eProcessAction::FULL_RENDER : (m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY)); }
void Fractorium::OnHighlightPowerChanged(double d) { m_Controller->HighlightPowerChanged(d); } void Fractorium::OnHighlightPowerChanged(double d) { m_Controller->HighlightPowerChanged(d); }
/// <summary> /// <summary>
@ -188,7 +188,7 @@ void Fractorium::OnColorSelected(const QColor& color) { m_Controller->Background
/// Resets the rendering process. /// Resets the rendering process.
/// </summary> /// </summary>
/// <param name="index">The index of the palette mode combo box</param> /// <param name="index">The index of the palette mode combo box</param>
template <typename T> void FractoriumEmberController<T>::PaletteModeChanged(uint i) { Update([&] { m_Ember.m_PaletteMode = i == 0 ? PALETTE_STEP : PALETTE_LINEAR; }); } template <typename T> void FractoriumEmberController<T>::PaletteModeChanged(uint i) { Update([&] { m_Ember.m_PaletteMode = i == 0 ? ePaletteMode::PALETTE_STEP : ePaletteMode::PALETTE_LINEAR; }); }
void Fractorium::OnPaletteModeComboCurrentIndexChanged(int index) { m_Controller->PaletteModeChanged(index); } void Fractorium::OnPaletteModeComboCurrentIndexChanged(int index) { m_Controller->PaletteModeChanged(index); }
/// <summary> /// <summary>
@ -302,7 +302,7 @@ void Fractorium::OnSpatialFilterTypeComboCurrentIndexChanged(const QString& text
/// In the future, when animation is implemented, this will have an effect. /// In the future, when animation is implemented, this will have an effect.
/// </summary> /// </summary>
/// <param name="d">The temporal filter width</param> /// <param name="d">The temporal filter width</param>
template <typename T> void FractoriumEmberController<T>::TemporalFilterWidthChanged(double d) { Update([&] { m_Ember.m_TemporalFilterWidth = d; }, true, NOTHING); }//Don't do anything until animation is implemented. template <typename T> void FractoriumEmberController<T>::TemporalFilterWidthChanged(double d) { Update([&] { m_Ember.m_TemporalFilterWidth = d; }, true, eProcessAction::NOTHING); }//Don't do anything until animation is implemented.
void Fractorium::OnTemporalFilterWidthChanged(double d) { m_Controller->TemporalFilterWidthChanged(d); } void Fractorium::OnTemporalFilterWidthChanged(double d) { m_Controller->TemporalFilterWidthChanged(d); }
/// <summary> /// <summary>
@ -312,7 +312,7 @@ void Fractorium::OnTemporalFilterWidthChanged(double d) { m_Controller->Temporal
/// In the future, when animation is implemented, this will have an effect. /// In the future, when animation is implemented, this will have an effect.
/// </summary> /// </summary>
/// <param name="text">The name of the temporal filter</param> /// <param name="text">The name of the temporal filter</param>
template <typename T> void FractoriumEmberController<T>::TemporalFilterTypeChanged(const QString& text) { Update([&] { m_Ember.m_TemporalFilterType = TemporalFilterCreator<T>::FromString(text.toStdString()); }, true, NOTHING); }//Don't do anything until animation is implemented. template <typename T> void FractoriumEmberController<T>::TemporalFilterTypeChanged(const QString& text) { Update([&] { m_Ember.m_TemporalFilterType = TemporalFilterCreator<T>::FromString(text.toStdString()); }, true, eProcessAction::NOTHING); }//Don't do anything until animation is implemented.
void Fractorium::OnTemporalFilterTypeComboCurrentIndexChanged(const QString& text) { m_Controller->TemporalFilterTypeChanged(text); } void Fractorium::OnTemporalFilterTypeComboCurrentIndexChanged(const QString& text) { m_Controller->TemporalFilterTypeChanged(text); }
/// <summary> /// <summary>
@ -399,7 +399,7 @@ void Fractorium::OnFuseChanged(int d) { m_Controller->FuseChanged(d); }
/// the rendering process is continued, else it's reset. /// the rendering process is continued, else it's reset.
/// </summary> /// </summary>
/// <param name="d">The quality in terms of iterations per pixel</param> /// <param name="d">The quality in terms of iterations per pixel</param>
template <typename T> void FractoriumEmberController<T>::QualityChanged(double d) { /*Update([&] { m_Ember.m_Quality = d; }, true, d > m_Ember.m_Quality ? KEEP_ITERATING : FULL_RENDER);*/ } template <typename T> void FractoriumEmberController<T>::QualityChanged(double d) { /*Update([&] { m_Ember.m_Quality = d; }, true, d > m_Ember.m_Quality ? KEEP_ITERATING : eProcessAction::FULL_RENDER);*/ }
void Fractorium::OnQualityChanged(double d) { /*m_Controller->QualityChanged(d);*/ } void Fractorium::OnQualityChanged(double d) { /*m_Controller->QualityChanged(d);*/ }
/// <summary> /// <summary>
@ -423,7 +423,7 @@ void Fractorium::OnSupersampleChanged(int d) { m_Controller->SupersampleChanged(
/// In the future, when animation is implemented, this will have an effect. /// In the future, when animation is implemented, this will have an effect.
/// </summary> /// </summary>
/// <param name="d">The temporal samples value</param> /// <param name="d">The temporal samples value</param>
template <typename T> void FractoriumEmberController<T>::TemporalSamplesChanged(int i) { Update([&] { m_Ember.m_TemporalSamples = i; }, true, NOTHING); }//Don't do anything until animation is implemented. template <typename T> void FractoriumEmberController<T>::TemporalSamplesChanged(int i) { Update([&] { m_Ember.m_TemporalSamples = i; }, true, eProcessAction::NOTHING); }//Don't do anything until animation is implemented.
void Fractorium::OnTemporalSamplesChanged(int d) { m_Controller->TemporalSamplesChanged(d); } void Fractorium::OnTemporalSamplesChanged(int d) { m_Controller->TemporalSamplesChanged(d); }
/// <summary> /// <summary>
@ -439,12 +439,12 @@ void FractoriumEmberController<T>::AffineInterpTypeChanged(int i)
Update([&] Update([&]
{ {
if (i == 0) if (i == 0)
m_Ember.m_AffineInterp = AFFINE_INTERP_LINEAR; m_Ember.m_AffineInterp = eAffineInterp::AFFINE_INTERP_LINEAR;
else if (i == 1) else if (i == 1)
m_Ember.m_AffineInterp = AFFINE_INTERP_LOG; m_Ember.m_AffineInterp = eAffineInterp::AFFINE_INTERP_LOG;
else else
m_Ember.m_AffineInterp = AFFINE_INTERP_LINEAR; m_Ember.m_AffineInterp = eAffineInterp::AFFINE_INTERP_LINEAR;
}, true, NOTHING); }, true, eProcessAction::NOTHING);
} }
void Fractorium::OnAffineInterpTypeComboCurrentIndexChanged(int index) { m_Controller->AffineInterpTypeChanged(index); } void Fractorium::OnAffineInterpTypeComboCurrentIndexChanged(int index) { m_Controller->AffineInterpTypeChanged(index); }
@ -462,12 +462,12 @@ void FractoriumEmberController<T>::InterpTypeChanged(int i)
Update([&] Update([&]
{ {
if (i == 0) if (i == 0)
m_Ember.m_Interp = EMBER_INTERP_LINEAR; m_Ember.m_Interp = eInterp::EMBER_INTERP_LINEAR;
else if (i == 1) else if (i == 1)
m_Ember.m_Interp = EMBER_INTERP_SMOOTH; m_Ember.m_Interp = eInterp::EMBER_INTERP_SMOOTH;
else else
m_Ember.m_Interp = EMBER_INTERP_LINEAR; m_Ember.m_Interp = eInterp::EMBER_INTERP_LINEAR;
}, true, NOTHING); }, true, eProcessAction::NOTHING);
} }
void Fractorium::OnInterpTypeComboCurrentIndexChanged(int index) { m_Controller->InterpTypeChanged(index); } void Fractorium::OnInterpTypeComboCurrentIndexChanged(int index) { m_Controller->InterpTypeChanged(index); }
@ -530,8 +530,8 @@ void FractoriumEmberController<T>::FillParamTablesAndPalette()
m_Fractorium->m_QualitySpin->SetValueStealth(m_Ember.m_Quality); m_Fractorium->m_QualitySpin->SetValueStealth(m_Ember.m_Quality);
m_Fractorium->m_SupersampleSpin->SetValueStealth(m_Ember.m_Supersample); m_Fractorium->m_SupersampleSpin->SetValueStealth(m_Ember.m_Supersample);
m_Fractorium->m_TemporalSamplesSpin->SetValueStealth(m_Ember.m_TemporalSamples); m_Fractorium->m_TemporalSamplesSpin->SetValueStealth(m_Ember.m_TemporalSamples);
m_Fractorium->m_AffineInterpTypeCombo->SetCurrentIndexStealth(m_Ember.m_AffineInterp); m_Fractorium->m_AffineInterpTypeCombo->SetCurrentIndexStealth(int(m_Ember.m_AffineInterp));
m_Fractorium->m_InterpTypeCombo->SetCurrentIndexStealth(m_Ember.m_Interp); m_Fractorium->m_InterpTypeCombo->SetCurrentIndexStealth(int(m_Ember.m_Interp));
//Palette related items: //Palette related items:
//The temp palette is assigned the palette read when the file was parsed/saved. The user can apply adjustments on the GUI later. //The temp palette is assigned the palette read when the file was parsed/saved. The user can apply adjustments on the GUI later.
//These adjustments will be applied to the temp palette, then assigned back to m_Ember.m_Palette. //These adjustments will be applied to the temp palette, then assigned back to m_Ember.m_Palette.

View File

@ -201,7 +201,7 @@ void FractoriumEmberControllerBase::AddProcessAction(eProcessAction action)
eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions() eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions()
{ {
m_Cs.Enter(); m_Cs.Enter();
eProcessAction action = NOTHING; auto action = eProcessAction::NOTHING;
for (auto a : m_ProcessActions) for (auto a : m_ProcessActions)
if (a > action) if (a > action)
@ -310,7 +310,7 @@ bool FractoriumEmberController<T>::Render()
m_Ember.m_Quality = d; m_Ember.m_Quality = d;
qualityAction = eProcessAction::FULL_RENDER; qualityAction = eProcessAction::FULL_RENDER;
} }
else if (d > m_Ember.m_Quality && ProcessState() == ACCUM_DONE)//If quality increased, keep iterating after current render finishes. else if (d > m_Ember.m_Quality && ProcessState() == eProcessState::ACCUM_DONE)//If quality increased, keep iterating after current render finishes.
{ {
m_Ember.m_Quality = d; m_Ember.m_Quality = d;
qualityAction = eProcessAction::KEEP_ITERATING; qualityAction = eProcessAction::KEEP_ITERATING;
@ -332,7 +332,7 @@ bool FractoriumEmberController<T>::Render()
m_Ember.m_TemporalSamples = 1; m_Ember.m_TemporalSamples = 1;
//Take care of solo xforms and set the current ember and action. //Take care of solo xforms and set the current ember and action.
if (action != NOTHING) if (action != eProcessAction::NOTHING)
{ {
int i, solo = m_Fractorium->ui.CurrentXformCombo->property("soloxform").toInt(); int i, solo = m_Fractorium->ui.CurrentXformCombo->property("soloxform").toInt();
@ -361,12 +361,12 @@ bool FractoriumEmberController<T>::Render()
//Ensure sizes are equal and if not, update dimensions. //Ensure sizes are equal and if not, update dimensions.
if (SyncSizes()) if (SyncSizes())
{ {
action = FULL_RENDER; action = eProcessAction::FULL_RENDER;
return true; return true;
} }
//Determining if a completely new rendering process is being started. //Determining if a completely new rendering process is being started.
bool iterBegin = ProcessState() == NONE; bool iterBegin = ProcessState() == eProcessState::NONE;
if (iterBegin) if (iterBegin)
{ {
@ -380,10 +380,10 @@ bool FractoriumEmberController<T>::Render()
} }
//If the rendering process hasn't finished, render with the current specified action. //If the rendering process hasn't finished, render with the current specified action.
if (ProcessState() != ACCUM_DONE) if (ProcessState() != eProcessState::ACCUM_DONE)
{ {
//if (m_Renderer->Run(m_FinalImage, 0) == RENDER_OK)//Full, non-incremental render for debugging. //if (m_Renderer->Run(m_FinalImage, 0) == RENDER_OK)//Full, non-incremental render for debugging.
if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, (iterBegin || m_Fractorium->m_Settings->ContinuousUpdate())) == RENDER_OK)//Force output on iterBegin or if the settings specify to always do it. if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, (iterBegin || m_Fractorium->m_Settings->ContinuousUpdate())) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it.
{ {
//The amount to increment sub batch while rendering proceeds is purely empirical. //The amount to increment sub batch while rendering proceeds is purely empirical.
//Change later if better values can be derived/observed. //Change later if better values can be derived/observed.
@ -401,7 +401,7 @@ bool FractoriumEmberController<T>::Render()
} }
//Rendering has finished, update final stats. //Rendering has finished, update final stats.
if (ProcessState() == ACCUM_DONE) if (ProcessState() == eProcessState::ACCUM_DONE)
{ {
EmberStats stats = m_Renderer->Stats(); EmberStats stats = m_Renderer->Stats();
QString iters = ToString<qulonglong>(stats.m_Iters); QString iters = ToString<qulonglong>(stats.m_Iters);
@ -454,7 +454,7 @@ bool FractoriumEmberController<T>::Render()
//Update the GL window on start because the output will be forced. //Update the GL window on start because the output will be forced.
//Update it on finish because the rendering process is completely done. //Update it on finish because the rendering process is completely done.
if (iterBegin || ProcessState() == ACCUM_DONE) if (iterBegin || ProcessState() == eProcessState::ACCUM_DONE)
{ {
if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed. if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed.
gl->update(); gl->update();
@ -500,7 +500,7 @@ bool FractoriumEmberController<T>::Render()
} }
//Upon finishing, or having nothing to do, rest. //Upon finishing, or having nothing to do, rest.
if (ProcessState() == ACCUM_DONE) if (ProcessState() == eProcessState::ACCUM_DONE)
QThread::msleep(1); QThread::msleep(1);
//QApplication::processEvents(); //QApplication::processEvents();
@ -578,10 +578,10 @@ bool FractoriumEmberController<T>::CreateRenderer(eRendererType renderType, cons
m_Renderer->ThreadCount(s->ThreadCount()); m_Renderer->ThreadCount(s->ThreadCount());
m_Renderer->Transparency(s->Transparency()); m_Renderer->Transparency(s->Transparency());
if (m_Renderer->RendererType() == CPU_RENDERER) if (m_Renderer->RendererType() == eRendererType::CPU_RENDERER)
m_Renderer->InteractiveFilter(s->CpuDEFilter() ? FILTER_DE : FILTER_LOG); m_Renderer->InteractiveFilter(s->CpuDEFilter() ? eInteractiveFilter::FILTER_DE : eInteractiveFilter::FILTER_LOG);
else else
m_Renderer->InteractiveFilter(s->OpenCLDEFilter() ? FILTER_DE : FILTER_LOG); m_Renderer->InteractiveFilter(s->OpenCLDEFilter() ? eInteractiveFilter::FILTER_DE : eInteractiveFilter::FILTER_LOG);
if ((m_Renderer->EarlyClip() != m_PreviewRenderer->EarlyClip()) || if ((m_Renderer->EarlyClip() != m_PreviewRenderer->EarlyClip()) ||
(m_Renderer->YAxisUp() != m_PreviewRenderer->YAxisUp())) (m_Renderer->YAxisUp() != m_PreviewRenderer->YAxisUp()))

View File

@ -45,12 +45,11 @@ void FractoriumSettings::EnsureDefaults()
FinalThreadCount(Timing::ProcessorCount()); FinalThreadCount(Timing::ProcessorCount());
FinalThreadPriority(Clamp<int>(FinalThreadPriority(), (int)eThreadPriority::LOWEST, (int)eThreadPriority::HIGHEST)); FinalThreadPriority(Clamp<int>(FinalThreadPriority(), (int)eThreadPriority::LOWEST, (int)eThreadPriority::HIGHEST));
CpuSubBatch(std::max(1u, CpuSubBatch())); CpuSubBatch(std::max(1u, CpuSubBatch()));
OpenCLSubBatch(std::max(1u, OpenCLSubBatch())); OpenCLSubBatch(std::max(1u, OpenCLSubBatch()));
RandomCount(std::max(1u, RandomCount())); RandomCount(std::max(1u, RandomCount()));
if (FinalScale() > SCALE_HEIGHT) if (FinalScale() > int(eScaleType::SCALE_HEIGHT))
FinalScale(0); FinalScale(0);
if (OpenXmlExt() == "") if (OpenXmlExt() == "")

View File

@ -7,27 +7,22 @@
void Fractorium::InitXformsColorUI() void Fractorium::InitXformsColorUI()
{ {
int spinHeight = 20, row = 0; int spinHeight = 20, row = 0;
m_XformColorValueItem = new QTableWidgetItem(); m_XformColorValueItem = new QTableWidgetItem();
ui.XformColorIndexTable->setItem(0, 0, m_XformColorValueItem); ui.XformColorIndexTable->setItem(0, 0, m_XformColorValueItem);
m_PaletteRefItem = new QTableWidgetItem(); m_PaletteRefItem = new QTableWidgetItem();
ui.XformPaletteRefTable->setItem(0, 0, m_PaletteRefItem); ui.XformPaletteRefTable->setItem(0, 0, m_PaletteRefItem);
ui.XformPaletteRefTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui.XformPaletteRefTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
connect(ui.XformPaletteRefTable->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(OnXformRefPaletteResized(int, int, int)), Qt::QueuedConnection); connect(ui.XformPaletteRefTable->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(OnXformRefPaletteResized(int, int, int)), Qt::QueuedConnection);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorIndexTable, this, row, 1, m_XformColorIndexSpin, spinHeight, 0, 1, 0.01, SIGNAL(valueChanged(double)), SLOT(OnXformColorIndexChanged(double)), false, 0, 1, 0); SetupSpinner<DoubleSpinBox, double>(ui.XformColorIndexTable, this, row, 1, m_XformColorIndexSpin, spinHeight, 0, 1, 0.01, SIGNAL(valueChanged(double)), SLOT(OnXformColorIndexChanged(double)), false, 0, 1, 0);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformColorSpeedSpin, spinHeight, -1, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformColorSpeedChanged(double)), true, 0.5, 0.5, 0.5); SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformColorSpeedSpin, spinHeight, -1, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformColorSpeedChanged(double)), true, 0.5, 0.5, 0.5);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformOpacitySpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformOpacityChanged(double)), true, 1, 1, 0); SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformOpacitySpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformOpacityChanged(double)), true, 1, 1, 0);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformDirectColorSpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformDirectColorChanged(double)), true, 1, 1, 0); SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformDirectColorSpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformDirectColorChanged(double)), true, 1, 1, 0);
m_XformColorIndexSpin->setDecimals(3); m_XformColorIndexSpin->setDecimals(3);
m_XformColorSpeedSpin->setDecimals(3); m_XformColorSpeedSpin->setDecimals(3);
m_XformOpacitySpin->setDecimals(3); m_XformOpacitySpin->setDecimals(3);
m_XformDirectColorSpin->setDecimals(3); m_XformDirectColorSpin->setDecimals(3);
connect(ui.XformColorScroll, SIGNAL(valueChanged(int)), this, SLOT(OnXformScrollColorIndexChanged(int)), Qt::QueuedConnection); connect(ui.XformColorScroll, SIGNAL(valueChanged(int)), this, SLOT(OnXformScrollColorIndexChanged(int)), Qt::QueuedConnection);
connect(ui.SoloXformCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSoloXformCheckBoxStateChanged(int)), Qt::QueuedConnection); connect(ui.SoloXformCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSoloXformCheckBoxStateChanged(int)), Qt::QueuedConnection);
connect(ui.ResetCurvesButton, SIGNAL(clicked(bool)), this, SLOT(OnResetCurvesButtonClicked(bool)), Qt::QueuedConnection); connect(ui.ResetCurvesButton, SIGNAL(clicked(bool)), this, SLOT(OnResetCurvesButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.CurvesView, SIGNAL(PointChangedSignal(int, int, const QPointF&)), this, SLOT(OnCurvesPointChanged(int, int, const QPointF&)), Qt::QueuedConnection); connect(ui.CurvesView, SIGNAL(PointChangedSignal(int, int, const QPointF&)), this, SLOT(OnCurvesPointChanged(int, int, const QPointF&)), Qt::QueuedConnection);
connect(ui.CurvesAllRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesAllRadioButtonToggled(bool)), Qt::QueuedConnection); connect(ui.CurvesAllRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesAllRadioButtonToggled(bool)), Qt::QueuedConnection);
@ -49,11 +44,9 @@ void FractoriumEmberController<T>::XformColorIndexChanged(double d, bool updateR
{ {
auto scroll = m_Fractorium->ui.XformColorScroll; auto scroll = m_Fractorium->ui.XformColorScroll;
int scrollVal = d * scroll->maximum(); int scrollVal = d * scroll->maximum();
scroll->blockSignals(true); scroll->blockSignals(true);
scroll->setValue(scrollVal); scroll->setValue(scrollVal);
scroll->blockSignals(false); scroll->blockSignals(false);
SetCurrentXformColorIndex(d, updateRender); SetCurrentXformColorIndex(d, updateRender);
} }
@ -143,7 +136,6 @@ void Fractorium::OnSoloXformCheckBoxStateChanged(int state)
void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int newSize) void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int newSize)
{ {
QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage()); QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage());
SetPaletteTableItem(&pixmap, ui.XformPaletteRefTable, m_PaletteRefItem, 0, 0); SetPaletteTableItem(&pixmap, ui.XformPaletteRefTable, m_PaletteRefItem, 0, 0);
} }
@ -158,8 +150,7 @@ void FractoriumEmberController<T>::ClearColorCurves()
Update([&] Update([&]
{ {
m_Ember.m_Curves.Init(); m_Ember.m_Curves.Init();
}, true, m_Renderer->EarlyClip() ? FILTER_AND_ACCUM : ACCUM_ONLY); }, true, m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY);
FillCurvesControl(); FillCurvesControl();
} }
@ -180,7 +171,7 @@ void FractoriumEmberController<T>::ColorCurveChanged(int curveIndex, int pointIn
{ {
m_Ember.m_Curves.m_Points[curveIndex][pointIndex].x = point.x(); m_Ember.m_Curves.m_Points[curveIndex][pointIndex].x = point.x();
m_Ember.m_Curves.m_Points[curveIndex][pointIndex].y = point.y(); m_Ember.m_Curves.m_Points[curveIndex][pointIndex].y = point.y();
}, true, m_Renderer->EarlyClip() ? FILTER_AND_ACCUM : ACCUM_ONLY); }, true, m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY);
} }
void Fractorium::OnCurvesPointChanged(int curveIndex, int pointIndex, const QPointF& point) { m_Controller->ColorCurveChanged(curveIndex, pointIndex, point); } void Fractorium::OnCurvesPointChanged(int curveIndex, int pointIndex, const QPointF& point) { m_Controller->ColorCurveChanged(curveIndex, pointIndex, point); }
@ -206,11 +197,9 @@ template <typename T>
QColor FractoriumEmberController<T>::ColorIndexToQColor(double d) QColor FractoriumEmberController<T>::ColorIndexToQColor(double d)
{ {
v4T entry = m_Ember.m_Palette[Clamp<int>(d * COLORMAP_LENGTH_MINUS_1, 0, m_Ember.m_Palette.Size())]; v4T entry = m_Ember.m_Palette[Clamp<int>(d * COLORMAP_LENGTH_MINUS_1, 0, m_Ember.m_Palette.Size())];
entry.r *= 255; entry.r *= 255;
entry.g *= 255; entry.g *= 255;
entry.b *= 255; entry.b *= 255;
QRgb rgb = uint(entry.r) << 16 | uint(entry.g) << 8 | uint(entry.b); QRgb rgb = uint(entry.r) << 16 | uint(entry.g) << 8 | uint(entry.b);
return QColor::fromRgb(rgb); return QColor::fromRgb(rgb);
} }
@ -226,7 +215,6 @@ void FractoriumEmberController<T>::SetCurrentXformColorIndex(double d, bool upda
UpdateXform([&] (Xform<T>* xform) UpdateXform([&] (Xform<T>* xform)
{ {
xform->m_ColorX = Clamp<T>(d, 0, 1); xform->m_ColorX = Clamp<T>(d, 0, 1);
//Grab the current color from the index and assign it to the first cell of the first table. //Grab the current color from the index and assign it to the first cell of the first table.
m_Fractorium->ui.XformColorIndexTable->item(0, 0)->setBackgroundColor(ColorIndexToQColor(xform->m_ColorX)/*QColor::fromRgb(rgb)*/); m_Fractorium->ui.XformColorIndexTable->item(0, 0)->setBackgroundColor(ColorIndexToQColor(xform->m_ColorX)/*QColor::fromRgb(rgb)*/);
}, eXformUpdate::UPDATE_SELECTED, updateRender); }, eXformUpdate::UPDATE_SELECTED, updateRender);
@ -245,7 +233,6 @@ void FractoriumEmberController<T>::FillCurvesControl()
for (size_t j = 1; j < 3; j++)//Only do middle points. for (size_t j = 1; j < 3; j++)//Only do middle points.
{ {
QPointF point(m_Ember.m_Curves.m_Points[i][j].x, m_Ember.m_Curves.m_Points[i][j].y); QPointF point(m_Ember.m_Curves.m_Points[i][j].x, m_Ember.m_Curves.m_Points[i][j].y);
m_Fractorium->ui.CurvesView->Set(i, j, point); m_Fractorium->ui.CurvesView->Set(i, j, point);
} }
} }
@ -290,5 +277,5 @@ void Fractorium::SetPaletteTableItem(QPixmap* pixmap, QTableWidget* table, QTabl
template class FractoriumEmberController<float>; template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
template class FractoriumEmberController<double>; template class FractoriumEmberController<double>;
#endif #endif