diff --git a/Builds/MSVC/VS2013/Fractorium.sln b/Builds/MSVC/VS2013/Fractorium.sln index 06ed50c..c4666f2 100644 --- a/Builds/MSVC/VS2013/Fractorium.sln +++ b/Builds/MSVC/VS2013/Fractorium.sln @@ -228,6 +228,7 @@ Global {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release|Win32.ActiveCfg = Release|Win32 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release|Win32.Build.0 = Release|Win32 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release|x64.ActiveCfg = Release|x64 + {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release|x64.Build.0 = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release|x86.ActiveCfg = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release-MT|Mixed Platforms.ActiveCfg = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.Release-MT|Mixed Platforms.Build.0 = Release|x64 @@ -239,6 +240,7 @@ Global {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseNvidia|Mixed Platforms.Build.0 = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseNvidia|Win32.ActiveCfg = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseNvidia|x64.ActiveCfg = ReleaseNvidia|x64 + {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseNvidia|x64.Build.0 = ReleaseNvidia|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseNvidia|x86.ActiveCfg = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseWithoutAsm|Mixed Platforms.ActiveCfg = Release|x64 {320F611A-F9CE-4196-A8DC-FA24B2E8A320}.ReleaseWithoutAsm|Mixed Platforms.Build.0 = Release|x64 @@ -952,7 +954,6 @@ Global {C8096C47-E358-438C-A520-146D46B0637D}.Debug|Win32.ActiveCfg = Debug|x86 {C8096C47-E358-438C-A520-146D46B0637D}.Debug|Win32.Build.0 = Debug|x86 {C8096C47-E358-438C-A520-146D46B0637D}.Debug|x64.ActiveCfg = Debug|x64 - {C8096C47-E358-438C-A520-146D46B0637D}.Debug|x64.Build.0 = Debug|x64 {C8096C47-E358-438C-A520-146D46B0637D}.Debug|x86.ActiveCfg = Debug|x86 {C8096C47-E358-438C-A520-146D46B0637D}.Debug|x86.Build.0 = Debug|x86 {C8096C47-E358-438C-A520-146D46B0637D}.Debug-MT|Mixed Platforms.ActiveCfg = Debug|x86 diff --git a/Source/Ember/EmberDefines.h b/Source/Ember/EmberDefines.h index aa3aabf..fa9c212 100644 --- a/Source/Ember/EmberDefines.h +++ b/Source/Ember/EmberDefines.h @@ -62,6 +62,8 @@ namespace EmberNs #define CUBE(x) ((x) * (x) * (x)) #define TLOW std::numeric_limits::lowest() #define TMAX std::numeric_limits::max() +#define FLOAT_MAX_TAN 8388607.0f +#define FLOAT_MIN_TAN -FLOAT_MAX_TAN typedef std::chrono::high_resolution_clock Clock; #define DO_DOUBLE 1//Comment this out for shorter build times during development. Always uncomment for release. diff --git a/Source/Ember/Utils.h b/Source/Ember/Utils.h index 899f41a..8f4b9fb 100644 --- a/Source/Ember/Utils.h +++ b/Source/Ember/Utils.h @@ -16,7 +16,7 @@ namespace EmberNs /// The lambda to call on each element /// True if pred returned true once, else false. template -bool inline FindIf(c& container, pr pred) +static inline bool FindIf(c& container, pr pred) { return std::find_if(container.begin(), container.end(), pred) != container.end(); } @@ -28,7 +28,7 @@ bool inline FindIf(c& container, pr pred) /// The container to call for_each() on /// The lambda to call on each element template -void inline ForEach(c& container, fn func) +static inline void ForEach(c& container, fn func) { std::for_each(container.begin(), container.end(), func); } @@ -199,7 +199,7 @@ static bool ReadFile(const char* filename, string& buf, bool nullTerminate = tru /// The vector of type T to copy to /// The vector of type U to copy from template -void CopyVec(vector& dest, const vector& source) +static void CopyVec(vector& dest, const vector& source) { dest.clear(); dest.resize(source.size()); @@ -390,7 +390,7 @@ static inline void ClampGte0Ref(T& val) /// The value to round /// The rounded value template -T Round(T r) +static inline T Round(T r) { return (r > 0) ? (T)Floor(r + T(0.5)) : ceil(r - T(0.5)); } @@ -400,7 +400,7 @@ T Round(T r) /// /// The value to round /// The rounded value -inline float LRint(float x) +static inline float LRint(float x) { int temp = (x >= 0 ? (int)(x + 0.5f) : (int)(x - 0.5f)); return (float)temp; @@ -411,7 +411,7 @@ inline float LRint(float x) /// /// The value to round /// The rounded value -inline double LRint(double x) +static inline double LRint(double x) { int64_t temp = (x >= 0 ? (int64_t)(x + 0.5) : (int64_t)(x - 0.5)); return (double)temp; @@ -483,6 +483,30 @@ static inline T SafeSqrt(T x) return sqrt(x); } +template +static inline T SafeTan(T x) +{ + return x; +} + +template <> +#ifdef _WIN32 +static +#endif +float SafeTan(float x) +{ + return tan(Clamp(x, FLOAT_MIN_TAN, FLOAT_MAX_TAN)); +} + +template <> +#ifdef _WIN32 +static +#endif +double SafeTan(double x) +{ + return tan(x); +} + /// /// Return the cube of the passed in value. /// This is useful when the value is a result of a computation @@ -664,7 +688,7 @@ static inline bool IsNearZero(T val, T tolerance = 1e-6) /// The tolerance. Default: 1e-6. /// True if the values were very close to each other, else false template -static bool IsClose(T val1, T val2, T tolerance = 1e-6) +static inline bool IsClose(T val1, T val2, T tolerance = 1e-6) { return IsNearZero(val1 - val2, tolerance); } @@ -773,7 +797,7 @@ static inline string Trim(string& str, char ch = ' ') /// The default value to return if the environment variable was not present /// The value of the specified environment variable if found, else default template -static T Arg(char* name, T def) +static inline T Arg(char* name, T def) { T t; return t; @@ -923,7 +947,7 @@ string Arg(char* name, string def) /// The value to replace with /// The number of instances replaced template -unsigned int inline FindAndReplace(T& source, const T& find, const T& replace) +static unsigned int FindAndReplace(T& source, const T& find, const T& replace) { unsigned int replaceCount = 0; typename T::size_type fLen = find.size(); @@ -946,7 +970,7 @@ unsigned int inline FindAndReplace(T& source, const T& find, const T& replace) /// /// Return a character pointer to a version string composed of the EMBER_OS and EMBER_VERSION values. /// -static const char* EmberVersion() +static inline const char* EmberVersion() { return EMBER_OS "-" EMBER_VERSION; } diff --git a/Source/Ember/Variations01.h b/Source/Ember/Variations01.h index ec25f9e..41c8471 100644 --- a/Source/Ember/Variations01.h +++ b/Source/Ember/Variations01.h @@ -815,8 +815,8 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T dx = tan(3 * helper.In.y); - T dy = tan(3 * helper.In.x); + T dx = SafeTan(3 * helper.In.y); + T dy = SafeTan(3 * helper.In.x); T nx = helper.In.x + m_Xform->m_Affine.C() * sin(dx); T ny = helper.In.y + m_Xform->m_Affine.F() * sin(dy); @@ -2428,7 +2428,7 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { helper.Out.x = m_Weight * sin(helper.In.x) / cos(helper.In.y); - helper.Out.y = m_Weight * tan(helper.In.y); + helper.Out.y = m_Weight * SafeTan(helper.In.y); helper.Out.z = m_Weight * helper.In.z; } @@ -2495,7 +2495,7 @@ public: { T ang = m_Weight * rand.Frand01() * T(M_PI); T r = m_Weight / Zeps(helper.m_PrecalcSumSquares); - T tanr = m_Weight * tan(ang) * r; + T tanr = m_Weight * SafeTan(ang) * r; helper.Out.x = tanr * cos(helper.In.x); helper.Out.y = tanr * sin(helper.In.y); @@ -4596,8 +4596,8 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - helper.Out.x = m_Weight * (helper.In.x + m_X * sin(tan(helper.In.y * m_C))); - helper.Out.y = m_Weight * (helper.In.y + m_Y * sin(tan(helper.In.x * m_C))); + helper.Out.x = m_Weight * (helper.In.x + m_X * sin(SafeTan(helper.In.y * m_C))); + helper.Out.y = m_Weight * (helper.In.y + m_Y * sin(SafeTan(helper.In.x * m_C))); helper.Out.z = m_Weight * helper.In.z; } diff --git a/Source/Ember/Variations02.h b/Source/Ember/Variations02.h index b6cd24a..1ca2172 100644 --- a/Source/Ember/Variations02.h +++ b/Source/Ember/Variations02.h @@ -5469,7 +5469,7 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - helper.Out.x = m_Weight01 / tan(helper.In.x) * cos(helper.In.y); + helper.Out.x = m_Weight01 / SafeTan(helper.In.x) * cos(helper.In.y); helper.Out.y = m_Weight01 / sin(helper.In.x) * (-helper.In.y); helper.Out.z = m_Weight * helper.In.z; } diff --git a/Source/Ember/Variations03.h b/Source/Ember/Variations03.h index 3dbab5c..6f3f4de 100644 --- a/Source/Ember/Variations03.h +++ b/Source/Ember/Variations03.h @@ -187,8 +187,8 @@ public: { T u = sqrt(ClampGte0(Zeps(m_A) * SQR(helper.In.x) + Zeps(m_B) * SQR(helper.In.y)));//Original did not clamp. - helper.Out.x = cos(u) * tan(helper.In.x) * m_Weight; - helper.Out.y = sin(u) * tan(helper.In.y) * m_Weight; + helper.Out.x = cos(u) * SafeTan(helper.In.x) * m_Weight; + helper.Out.y = sin(u) * SafeTan(helper.In.y) * m_Weight; helper.Out.z = m_Weight * helper.In.z; } diff --git a/Source/Ember/Variations05.h b/Source/Ember/Variations05.h index 34e026c..aa5d4d4 100644 --- a/Source/Ember/Variations05.h +++ b/Source/Ember/Variations05.h @@ -1636,8 +1636,8 @@ public: if (otherZ == 0) tempPZ = m_Vv * m_SinTanC * helper.m_PrecalcAtanyx; - helper.Out.x = m_HalfWeight * (helper.In.x + m_X * sin(tan(m_C * helper.In.y))); - helper.Out.y = m_HalfWeight * (helper.In.y + m_Y * sin(tan(m_C * helper.In.x))); + helper.Out.x = m_HalfWeight * (helper.In.x + m_X * sin(SafeTan(m_C * helper.In.y))); + helper.Out.y = m_HalfWeight * (helper.In.y + m_Y * sin(SafeTan(m_C * helper.In.x))); helper.Out.z = tempPZ + m_Vv * (m_Z * m_SinTanC * tempTZ); } @@ -1677,7 +1677,7 @@ public: virtual void Precalc() override { - m_SinTanC = sin(tan(m_C)); + m_SinTanC = sin(SafeTan(m_C)); m_HalfWeight = m_Weight * T(0.5); if (fabs(m_Weight) <= 1) diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp index bcb77ff..44a1db5 100644 --- a/Source/Fractorium/Fractorium.cpp +++ b/Source/Fractorium/Fractorium.cpp @@ -29,6 +29,10 @@ Fractorium::Fractorium(QWidget* parent) m_OptionsDialog = new FractoriumOptionsDialog(m_Settings, this); m_AboutDialog = new FractoriumAboutDialog(this); + //Put the about dialog in the screen center. + const QRect screen = QApplication::desktop()->screenGeometry(); + m_AboutDialog->move(screen.center() - m_AboutDialog->rect().center()); + //The options dialog should be a fixed size without a size grip, however even if it's here, it still shows up. Perhaps Qt will fix it some day. m_OptionsDialog->layout()->setSizeConstraint(QLayout::SetFixedSize); m_OptionsDialog->setSizeGripEnabled(false);