--Bug fixes

-Fix crash on palette editor when opening it with certain palette files in a particular order.
 -An xform with only a post variation in it might have showed up wrong.
 -The xforms combo box was obscuring the name of the xforms by not being wide enough.
 -Make variation state preservation be a little bit more correct in OpenCL.

--Code changes
 -Make all iterators on the CPU use a temporary point.
This commit is contained in:
Person
2020-02-17 18:45:02 -08:00
parent 8cd2340484
commit 8c66fa2c24
18 changed files with 341 additions and 119 deletions

View File

@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
namespace EmberNs
{
#define EMBER_VERSION "1.0.0.18"
#define EMBER_VERSION "1.0.0.19"
//#define FLAM3_COMPAT 1//Uncomment this if you want full compatibility with flam3 regarding some of the trig-based variations in Variations01.h
#define EPS6 T(1e-6)
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.

View File

@ -300,7 +300,7 @@ public:
virtual size_t Iterate(Ember<T>& ember, const IterParams<T> params, const CarToRas<T>& ctr, Point<T>* samples, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
size_t i, badVals = 0;
Point<T> tempPoint, p1;
Point<T> tempPoint, p1, p2;
auto xforms = ember.NonConstXforms();
if (ember.ProjBits())//No xaos, 3D.
@ -311,8 +311,10 @@ public:
for (i = 0; i < params.m_Skip; i++)//Fuse.
{
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p1, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p1, rand);
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p2, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p2, rand);
p1 = p2;
}
DoFinalXform(ember, p1, samples, rand);//Apply to last fuse point and store as the first element in samples.
@ -320,10 +322,11 @@ public:
for (i = 1; i < params.m_Count; i++)//Real loop.
{
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p1, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p1, rand);
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p2, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p2, rand);
DoFinalXform(ember, p1, samples + i, rand);
p1 = p2;
DoFinalXform(ember, p2, samples + i, rand);
ember.Proj(samples[i], rand, ctr);
}
}
@ -333,8 +336,10 @@ public:
for (i = 0; i < params.m_Skip; i++)//Fuse.
{
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p1, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p1, rand);
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p2, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p2, rand);
p1 = p2;
}
samples[0] = p1;
@ -358,18 +363,21 @@ public:
for (i = 0; i < params.m_Skip; i++)//Fuse.
{
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p1, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p1, rand);
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p2, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p2, rand);
p1 = p2;
}
DoFinalXform(ember, p1, samples, rand);//Apply to last fuse point and store as the first element in samples.
for (i = 1; i < params.m_Count; i++)//Real loop.
{
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p1, rand))//Feed the resulting value of applying the randomly selected xform back into the next iter, and not the result of applying the final xform.
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p1, rand);
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p2, rand))//Feed the resulting value of applying the randomly selected xform back into the next iter, and not the result of applying the final xform.
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p2, rand);
DoFinalXform(ember, p1, samples + i, rand);
p1 = p2;
DoFinalXform(ember, p2, samples + i, rand);
}
}
else//No xaos, no 3D, no final.
@ -378,8 +386,10 @@ public:
for (i = 0; i < params.m_Skip; i++)//Fuse.
{
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p1, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p1, rand);
if (xforms[NextXformFromIndex(rand.Rand())].Apply(&p1, &p2, rand))
DoBadVals(xforms, ember.m_RandPointRange, badVals, &p2, rand);
p1 = p2;
}
samples[0] = p1;
@ -468,7 +478,7 @@ public:
size_t i, xformIndex;
size_t lastXformUsed = 0;
size_t badVals = 0;
Point<T> tempPoint, p1;
Point<T> tempPoint, p1, p2;
auto xforms = ember.NonConstXforms();
if (ember.ProjBits())//Xaos, 3D.
@ -481,9 +491,10 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
p1 = p2;
lastXformUsed = xformIndex + 1;//Store the last used transform.
}
@ -494,10 +505,11 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))//Feed the resulting value of applying the randomly selected xform back into the next iter, and not the result of applying the final xform.
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))//Feed the resulting value of applying the randomly selected xform back into the next iter, and not the result of applying the final xform.
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
DoFinalXform(ember, p1, samples + i, rand);
p1 = p2;
DoFinalXform(ember, p2, samples + i, rand);
ember.Proj(samples[i], rand, ctr);
lastXformUsed = xformIndex + 1;//Store the last used transform.
}
@ -510,9 +522,10 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
p1 = p2;
lastXformUsed = xformIndex + 1;//Store the last used transform.
}
@ -523,10 +536,10 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
samples[i] = p1;
samples[i] = p1 = p2;
ember.Proj(samples[i], rand, ctr);
lastXformUsed = xformIndex + 1;//Store the last used transform.
}
@ -542,9 +555,10 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
p1 = p2;
lastXformUsed = xformIndex + 1;//Store the last used transform.
}
@ -554,10 +568,11 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))//Feed the resulting value of applying the randomly selected xform back into the next iter, and not the result of applying the final xform.
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))//Feed the resulting value of applying the randomly selected xform back into the next iter, and not the result of applying the final xform.
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
DoFinalXform(ember, p1, samples + i, rand);
p1 = p2;
DoFinalXform(ember, p2, samples + i, rand);
lastXformUsed = xformIndex + 1;//Store the last used transform.
}
}
@ -569,9 +584,10 @@ public:
{
xformIndex = NextXformFromIndex(rand.Rand(), lastXformUsed);
if (xforms[xformIndex].Apply(&p1, &p1, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p1, rand);
if (xforms[xformIndex].Apply(&p1, &p2, rand))
DoBadVals(xforms, xformIndex, ember.m_RandPointRange, lastXformUsed, badVals, &p2, rand);
p1 = p2;
lastXformUsed = xformIndex + 1;//Store the last used transform.
}

View File

@ -603,24 +603,24 @@ public:
outPoint->m_Opacity = m_Opacity;
iterHelper.m_Color.x = outPoint->m_ColorX = m_ColorSpeedCache + (m_OneMinusColorCache * inPoint->m_ColorX);
//Compute the pre affine portion of the transform.
//These x, y values are what get passed to the variations below.
//Note that they are not changed after this, except in the case of pre_ variations.
if (m_HasPre)
{
iterHelper.m_TransX = (m_Affine.A() * inPoint->m_X) + (m_Affine.B() * inPoint->m_Y) + m_Affine.C();
iterHelper.m_TransY = (m_Affine.D() * inPoint->m_X) + (m_Affine.E() * inPoint->m_Y) + m_Affine.F();
}
else
{
iterHelper.m_TransX = inPoint->m_X;
iterHelper.m_TransY = inPoint->m_Y;
}
iterHelper.m_TransZ = inPoint->m_Z;
if (m_HasPreOrRegularVars)
{
//Compute the pre affine portion of the transform.
//These x, y values are what get passed to the variations below.
//Note that they are not changed after this, except in the case of pre_ variations.
if (m_HasPre)
{
iterHelper.m_TransX = (m_Affine.A() * inPoint->m_X) + (m_Affine.B() * inPoint->m_Y) + m_Affine.C();
iterHelper.m_TransY = (m_Affine.D() * inPoint->m_X) + (m_Affine.E() * inPoint->m_Y) + m_Affine.F();
}
else
{
iterHelper.m_TransX = inPoint->m_X;
iterHelper.m_TransY = inPoint->m_Y;
}
iterHelper.m_TransZ = inPoint->m_Z;
//Apply pre_ variations, these don't affect outPoint, only iterHelper.m_TransX, Y, Z.
for (i = 0; i < PreVariationCount(); i++)
{