fractorium/Source/Ember/EmberDefines.h
Person 8086cfa731 22.21.4.2 4/19/2021
--User changes
 -Allow users to set the Exp value when using the Exp temporal filter type.
 -Set the default temporal filter type to be Box, which does not alter the palette values at all during animation. This is done to avoid confusion when using Gaussian or Exp which can produce darkened images.

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

--Code changes
 -Add a new member function SaveCurrentAsXml(QString filename = "") to the controllers which is only used for testing.
 -Modernize some C++ code.
2021-04-19 21:07:24 -06:00

351 lines
10 KiB
C++

#pragma once
#include "EmberPch.h"
/// <summary>
/// Basic #defines used throughout the library.
/// </summary>
#ifdef _WIN32
#if defined(BUILDING_EMBER)
#define EMBER_API __declspec(dllexport)
#else
#define EMBER_API __declspec(dllimport)
#endif
#else
#define EMBER_API
#define fopen_s(pFile,filename,mode) ((*(pFile)=fopen((filename),(mode)))==nullptr)
#define _stat stat
#define _fstat fstat
#define _stricmp strcasecmp
typedef int errno_t;
#endif
#define RESTRICT __restrict//This might make things faster, unsure if it really does though.
//#define RESTRICT
//Wrap the sincos function for Macs and PC.
#if defined(__APPLE__) || defined(_MSC_VER)
#define sincos(x, s, c) *(s)=std::sin(x); *(c)=std::cos(x);
#else
static void sincos(float x, float* s, float* c)
{
*s = std::sin(x);
*c = std::cos(x);
}
#endif
namespace EmberNs
{
#define EMBER_VERSION "22.21.4.2"
//#define FLAM3_COMPAT 1//Uncomment this if you want full compatibility with flam3 regarding some of the trig-based variations in Variations01.h
#define EPS6 T(1e-6)
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
#define ISAAC_SIZE 4
#define MEMALIGN 32
#define DE_THRESH 100
#define DEG_2_RAD (M_PI / 180)
#define RAD_2_DEG (180 / M_PI)
#define DEG_2_RAD_T (T{M_PI} / T{180})
#define RAD_2_DEG_T (T{180} / T{M_PI})
#define M_2PI (T{M_PI * 2})
#define M_3PI (T{M_PI * 3})
#define M_PI2 (T{M_PI_2})
#define M_PI4 (T{M_PI_4})
#define M_SQRT3 T(1.7320508075688772935274463415059)
#define M_SQRT3_2 T(0.86602540378443864676372317075294)
#define M_SQRT3_3 T(0.57735026918962576450914878050196)
#define M_SQRT5 T(2.2360679774997896964091736687313)
#define M_PHI T(1.61803398874989484820458683436563)
#define M_1_2PI T(0.15915494309189533576888376337251)
#define M_PI3 T(1.0471975511965977461542144610932)
#define M_PI6 T(0.52359877559829887307710723054658)
#define COLORMAP_LENGTH 256//These will need to change if 2D palette support is ever added, or variable sized palettes.
#define WHITE 255
#define DEFAULT_SBS (1024 * 10)
//#define XC(c) ((const xmlChar*)(c))
#define XC(c) (reinterpret_cast<const xmlChar*>(c))
#define CX(c) (reinterpret_cast<char*>(c))
#define CCX(c) (reinterpret_cast<const char*>(c))
#define BadVal(x) (std::isnan(x))
#define Vlen(x) (sizeof(x) / sizeof(*x))
#define SQR(x) ((x) * (x))
#define CUBE(x) ((x) * (x) * (x))
#define TLOW std::numeric_limits<T>::lowest()
#define TMAX std::numeric_limits<T>::max()
#define FLOAT_MAX_TAN 8388607.0f
#define FLOAT_MIN_TAN -FLOAT_MAX_TAN
#define CURVES_LENGTH 65536
#define CURVES_LENGTH_M1 65535.0f
#define ONE_OVER_CURVES_LENGTH_M1 1.525902189669e-5f
#define EMPTYFIELD -9999
typedef unsigned char et;
typedef std::lock_guard <std::recursive_mutex> rlg;
/// <summary>
/// Thin wrapper around getting the current time in milliseconds.
/// </summary>
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::duration<double, std::ratio<1, 1000>> DoubleMs;
typedef std::chrono::time_point<Clock, DoubleMs> DoubleMsTimePoint;
static inline DoubleMsTimePoint NowMsD() { return time_point_cast<DoubleMs>(Clock::now()); }
static inline size_t NowMs() { return duration_cast<milliseconds>(Clock::now().time_since_epoch()).count(); }
#ifndef byte
typedef unsigned char byte;
#endif
#define DO_DOUBLE 1//Comment this out for shorter build times during development. Always uncomment for release.
//#define ISAAC_FLAM3_DEBUG 1//This is almost never needed, but is very useful when troubleshooting difficult bugs. Enable it to do a side by side comparison with flam3.
//These two must always match.
#ifdef _WIN32
#define ALIGN __declspec(align(16))
#define STATIC static
#else
#define ALIGN __attribute__ ((aligned (16)))
#define STATIC
#endif
#define ALIGN_CL "((aligned (16)))"//The extra parens are necessary.
#if GLM_VERSION >= 96
#define v2T glm::tvec2<T, glm::defaultp>
#define v3T glm::tvec3<T, glm::defaultp>
#define v4T glm::tvec4<T, glm::defaultp>
#define v2F glm::tvec2<float, glm::defaultp>
#define v4F glm::tvec4<float, glm::defaultp>
#define v4D glm::tvec4<double, glm::defaultp>
#define v4bT glm::tvec4<bucketT, glm::defaultp>
#define m2T glm::tmat2x2<T, glm::defaultp>
#define m3T glm::tmat3x3<T, glm::defaultp>
#define m4T glm::tmat4x4<T, glm::defaultp>
#define m23T glm::tmat2x3<T, glm::defaultp>
typedef vector<glm::tvec4<float, glm::defaultp>> vv4F;
#else
#define v2T glm::detail::tvec2<T, glm::defaultp>
#define v3T glm::detail::tvec3<T, glm::defaultp>
#define v4T glm::detail::tvec4<T, glm::defaultp>
#define v2F glm::detail::tvec2<float, glm::defaultp>
#define v4F glm::detail::tvec4<float, glm::defaultp>
#define v4D glm::detail::tvec4<double, glm::defaultp>
#define v4bT glm::detail::tvec4<bucketT, glm::defaultp>
#define m2T glm::detail::tmat2x2<T, glm::defaultp>
#define m3T glm::detail::tmat3x3<T, glm::defaultp>
#define m4T glm::detail::tmat4x4<T, glm::defaultp>
#define m23T glm::detail::tmat2x3<T, glm::defaultp>
typedef vector<glm::detail::tvec4<float, glm::defaultp>> vv4F;
#endif
enum class eInterp : et { EMBER_INTERP_LINEAR = 0, EMBER_INTERP_SMOOTH = 1 };
enum class eAffineInterp : et { AFFINE_INTERP_LINEAR = 0, AFFINE_INTERP_LOG = 1, AFFINE_INTERP_COMPAT = 2, AFFINE_INTERP_OLDER = 3 };
enum class ePaletteMode : et { PALETTE_STEP = 0, PALETTE_LINEAR = 1 };
enum class ePaletteInterp : et { INTERP_HSV = 0, INTERP_SWEEP = 1 };
enum class eMotion : et { MOTION_SIN = 1, MOTION_TRIANGLE = 2, MOTION_HILL = 3, MOTION_SAW = 4 };
enum class eProcessAction : et { NOTHING = 0, ACCUM_ONLY = 1, FILTER_AND_ACCUM = 2, KEEP_ITERATING = 3, FULL_RENDER = 4 };
enum class eProcessState : et { NONE = 0, ITER_STARTED = 1, ITER_DONE = 2, FILTER_DONE = 3, ACCUM_DONE = 4 };
enum class eInteractiveFilter : et { FILTER_LOG = 0, FILTER_DE = 1 };
enum class eScaleType : et { SCALE_NONE = 0, SCALE_WIDTH = 1, SCALE_HEIGHT = 2 };
enum class eRenderStatus : et { RENDER_OK = 0, RENDER_ERROR = 1, RENDER_ABORT = 2 };
enum class eEmberMotionParam : et//These must remain in this order forever.
{
FLAME_MOTION_NONE,
FLAME_MOTION_ZOOM,
FLAME_MOTION_ZPOS,
FLAME_MOTION_PERSPECTIVE,
FLAME_MOTION_YAW,
FLAME_MOTION_PITCH,
FLAME_MOTION_DEPTH_BLUR,
FLAME_MOTION_CENTER_X,
FLAME_MOTION_CENTER_Y,
FLAME_MOTION_ROTATE,
FLAME_MOTION_BRIGHTNESS,
FLAME_MOTION_GAMMA,
FLAME_MOTION_GAMMA_THRESH,
FLAME_MOTION_HIGHLIGHT_POWER,
FLAME_MOTION_K2,
FLAME_MOTION_RAND_RANGE,
FLAME_MOTION_BACKGROUND_R,
FLAME_MOTION_BACKGROUND_G,
FLAME_MOTION_BACKGROUND_B,
FLAME_MOTION_VIBRANCY,
FLAME_MOTION_BLUR_CURVE
};
/// <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;
}
}