--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
+1 -1
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.
+49 -33
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.
}
+16 -16
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++)
{