From cc1b9bc619408ef2d0a39f59015cbb525af300fa Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 28 Mar 2016 19:46:29 -0300 Subject: [PATCH] Moved most love.math functions out of the Math class, since they're pure functions. --HG-- branch : minor --- src/modules/graphics/Graphics.cpp | 12 +- src/modules/graphics/opengl/Graphics.cpp | 2 +- src/modules/graphics/opengl/wrap_Shader.cpp | 3 +- src/modules/math/MathModule.cpp | 79 ++++----- src/modules/math/MathModule.h | 182 ++++++++++---------- src/modules/math/wrap_Math.cpp | 66 +++---- 6 files changed, 162 insertions(+), 182 deletions(-) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index cca874b09..9eb358cd2 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -42,9 +42,9 @@ void gammaCorrectColor(Colorf &c) { if (isGammaCorrect()) { - c.r = math::Math::instance.gammaToLinear(c.r); - c.g = math::Math::instance.gammaToLinear(c.g); - c.b = math::Math::instance.gammaToLinear(c.b); + c.r = math::gammaToLinear(c.r); + c.g = math::gammaToLinear(c.g); + c.b = math::gammaToLinear(c.b); } } @@ -52,9 +52,9 @@ void unGammaCorrectColor(Colorf &c) { if (isGammaCorrect()) { - c.r = math::Math::instance.linearToGamma(c.r); - c.g = math::Math::instance.linearToGamma(c.g); - c.b = math::Math::instance.linearToGamma(c.b); + c.r = math::linearToGamma(c.r); + c.g = math::linearToGamma(c.g); + c.b = math::linearToGamma(c.b); } } diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 0b5b928d9..93bffed29 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -490,7 +490,7 @@ void Graphics::clear(const std::vector &colors) if (isGammaCorrect()) { for (int i = 0; i < 3; i++) - c[i] = math::Math::instance.gammaToLinear(c[i]); + c[i] = math::gammaToLinear(c[i]); } if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0) diff --git a/src/modules/graphics/opengl/wrap_Shader.cpp b/src/modules/graphics/opengl/wrap_Shader.cpp index a9dbacfef..dcf1ff419 100644 --- a/src/modules/graphics/opengl/wrap_Shader.cpp +++ b/src/modules/graphics/opengl/wrap_Shader.cpp @@ -159,12 +159,11 @@ static int w__Shader_sendFloat(lua_State *L, bool colors) { // the fourth component (alpha) is always already linear, if it exists. int ncomponents = std::min((int) dimension, 3); - const auto &m = love::math::Math::instance; for (int i = 0; i < count; i++) { for (int j = 0; j < ncomponents; j++) - values[i * dimension + j] = m.gammaToLinear(values[i * dimension + j]); + values[i * dimension + j] = math::gammaToLinear(values[i * dimension + j]); } } diff --git a/src/modules/math/MathModule.cpp b/src/modules/math/MathModule.cpp index a6a22b0a2..79417e758 100644 --- a/src/modules/math/MathModule.cpp +++ b/src/modules/math/MathModule.cpp @@ -23,6 +23,7 @@ #include "common/Vector.h" #include "common/b64.h" #include "common/int.h" +#include "common/StringMap.h" #include "BezierCurve.h" // STL @@ -164,30 +165,7 @@ namespace love namespace math { -Math Math::instance; - -Math::Math() - : rng() -{ - // prevent the runtime from free()-ing this - retain(); -} - -Math::~Math() -{ -} - -RandomGenerator *Math::newRandomGenerator() -{ - return new RandomGenerator(); -} - -BezierCurve *Math::newBezierCurve(const vector &points) -{ - return new BezierCurve(points); -} - -vector Math::triangulate(const vector &polygon) +vector triangulate(const vector &polygon) { if (polygon.size() < 3) throw love::Exception("Not a polygon"); @@ -252,7 +230,7 @@ vector Math::triangulate(const vector &polygon) return triangles; } -bool Math::isConvex(const std::vector &polygon) +bool isConvex(const std::vector &polygon) { if (polygon.size() < 3) return false; @@ -282,7 +260,7 @@ bool Math::isConvex(const std::vector &polygon) /** * http://en.wikipedia.org/wiki/SRGB#The_reverse_transformation **/ -float Math::gammaToLinear(float c) const +float gammaToLinear(float c) { if (c <= 0.04045f) return c / 12.92f; @@ -293,7 +271,7 @@ float Math::gammaToLinear(float c) const /** * http://en.wikipedia.org/wiki/SRGB#The_forward_transformation_.28CIE_xyY_or_CIE_XYZ_to_sRGB.29 **/ -float Math::linearToGamma(float c) const +float linearToGamma(float c) { if (c <= 0.0031308f) return c * 12.92f; @@ -301,12 +279,12 @@ float Math::linearToGamma(float c) const return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; } -CompressedData *Math::compress(Compressor::Format format, love::Data *rawdata, int level) +CompressedData *compress(Compressor::Format format, love::Data *rawdata, int level) { return compress(format, (const char *) rawdata->getData(), rawdata->getSize(), level); } -CompressedData *Math::compress(Compressor::Format format, const char *rawbytes, size_t rawsize, int level) +CompressedData *compress(Compressor::Format format, const char *rawbytes, size_t rawsize, int level) { Compressor *compressor = Compressor::getCompressor(format); @@ -331,7 +309,7 @@ CompressedData *Math::compress(Compressor::Format format, const char *rawbytes, return data; } -char *Math::decompress(CompressedData *data, size_t &decompressedsize) +char *decompress(CompressedData *data, size_t &decompressedsize) { size_t rawsize = data->getDecompressedSize(); @@ -342,7 +320,7 @@ char *Math::decompress(CompressedData *data, size_t &decompressedsize) return rawbytes; } -char *Math::decompress(Compressor::Format format, const char *cbytes, size_t compressedsize, size_t &rawsize) +char *decompress(Compressor::Format format, const char *cbytes, size_t compressedsize, size_t &rawsize) { Compressor *compressor = Compressor::getCompressor(format); @@ -352,7 +330,7 @@ char *Math::decompress(Compressor::Format format, const char *cbytes, size_t com return compressor->decompress(format, cbytes, compressedsize, rawsize); } -char *Math::encode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen, size_t linelen) +char *encode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen, size_t linelen) { switch (format) { @@ -364,7 +342,7 @@ char *Math::encode(EncodeFormat format, const char *src, size_t srclen, size_t & } } -char *Math::decode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen) +char *decode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen) { switch (format) { @@ -376,23 +354,46 @@ char *Math::decode(EncodeFormat format, const char *src, size_t srclen, size_t & } } -bool Math::getConstant(const char *in, EncodeFormat &out) +Math Math::instance; + +Math::Math() + : rng() { - return encoders.find(in, out); + // prevent the runtime from free()-ing this + retain(); } -bool Math::getConstant(EncodeFormat in, const char *&out) +Math::~Math() { - return encoders.find(in, out); } -StringMap::Entry Math::encoderEntries[] = +RandomGenerator *Math::newRandomGenerator() +{ + return new RandomGenerator(); +} + +BezierCurve *Math::newBezierCurve(const vector &points) +{ + return new BezierCurve(points); +} + +static StringMap::Entry encoderEntries[] = { { "base64", ENCODE_BASE64 }, { "hex", ENCODE_HEX }, }; -StringMap Math::encoders(Math::encoderEntries, sizeof(Math::encoderEntries)); +static StringMap encoders(encoderEntries, sizeof(encoderEntries)); + +bool getConstant(const char *in, EncodeFormat &out) +{ + return encoders.find(in, out); +} + +bool getConstant(EncodeFormat in, const char *&out) +{ + return encoders.find(in, out); +} } // math } // love diff --git a/src/modules/math/MathModule.h b/src/modules/math/MathModule.h index 8217e193b..5ef0a7397 100644 --- a/src/modules/math/MathModule.h +++ b/src/modules/math/MathModule.h @@ -30,7 +30,6 @@ #include "common/math.h" #include "common/Vector.h" #include "common/int.h" -#include "common/StringMap.h" // Noise #include "libraries/noise1234/noise1234.h" @@ -46,6 +45,91 @@ namespace math class BezierCurve; +enum EncodeFormat +{ + ENCODE_BASE64, + ENCODE_HEX, + ENCODE_MAX_ENUM +}; + +/** + * Triangulate a simple polygon. + * + * @param polygon Polygon to triangulate. Must not intersect itself. + * @return List of triangles the polygon is composed of. + **/ +std::vector triangulate(const std::vector &polygon); + +/** + * Checks whether a polygon is convex. + * + * @param polygon Polygon to test. + * @return True if the polygon is convex, false otherwise. + **/ +bool isConvex(const std::vector &polygon); + +/** + * Converts a value from the sRGB (gamma) colorspace to linear RGB. + **/ +float gammaToLinear(float c); + +/** + * Converts a value from linear RGB to the sRGB (gamma) colorspace. + **/ +float linearToGamma(float c); + +/** + * Calculate noise for the specified coordinate(s). + * + * @return Noise value in the range of [0, 1]. + **/ +static float noise1(float x); +static float noise2(float x, float y); +static float noise3(float x, float y, float z); +static float noise4(float x, float y, float z, float w); + +/** + * Compresses a block of memory using the given compression format. + * + * @param format The compression format to use. + * @param rawdata The data to compress. + * @param level The amount of compression to apply (between 0 and 9.) + * A value of -1 indicates the default amount of compression. + * Specific formats may not use every level. + * @return The newly compressed data. + **/ +CompressedData *compress(Compressor::Format format, Data *rawdata, int level = -1); +CompressedData *compress(Compressor::Format format, const char *rawbytes, size_t rawsize, int level = -1); + +/** + * Decompresses existing compressed data into raw bytes. + * + * @param[in] data The compressed data to decompress. + * @param[out] decompressedsize The size in bytes of the decompressed data. + * @return The newly decompressed data (allocated with new[]). + **/ +char *decompress(CompressedData *data, size_t &decompressedsize); + +/** + * Decompresses existing compressed data into raw bytes. + * + * @param[in] format The compression format the data is in. + * @param[in] cbytes The compressed data to decompress. + * @param[in] compressedsize The size in bytes of the compressed data. + * @param[in,out] rawsize On input, the size in bytes of the original + * uncompressed data, or 0 if unknown. On return, the size in + * bytes of the newly decompressed data. + * @return The newly decompressed data (allocated with new[]). + **/ +char *decompress(Compressor::Format format, const char *cbytes, size_t compressedsize, size_t &rawsize); + +char *encode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen, size_t linelen = 0); +char *decode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen); + +bool getConstant(const char *in, EncodeFormat &out); +bool getConstant(EncodeFormat in, const char *&out); + + class Math : public Module { private: @@ -54,13 +138,6 @@ private: public: - enum EncodeFormat - { - ENCODE_BASE64, - ENCODE_HEX, - ENCODE_MAX_ENUM - }; - virtual ~Math(); RandomGenerator *getRandomGenerator() @@ -89,100 +166,21 @@ public: return "love.math"; } - /** - * Triangulate a simple polygon. - * - * @param polygon Polygon to triangulate. Must not intersect itself. - * @return List of triangles the polygon is composed of. - **/ - std::vector triangulate(const std::vector &polygon); - - /** - * Checks whether a polygon is convex. - * - * @param polygon Polygon to test. - * @return True if the polygon is convex, false otherwise. - **/ - bool isConvex(const std::vector &polygon); - - /** - * Converts a value from the sRGB (gamma) colorspace to linear RGB. - **/ - float gammaToLinear(float c) const; - - /** - * Converts a value from linear RGB to the sRGB (gamma) colorspace. - **/ - float linearToGamma(float c) const; - - /** - * Calculate noise for the specified coordinate(s). - * - * @return Noise value in the range of [0, 1]. - **/ - float noise(float x) const; - float noise(float x, float y) const; - float noise(float x, float y, float z) const; - float noise(float x, float y, float z, float w) const; - - /** - * Compresses a block of memory using the given compression format. - * - * @param format The compression format to use. - * @param rawdata The data to compress. - * @param level The amount of compression to apply (between 0 and 9.) - * A value of -1 indicates the default amount of compression. - * Specific formats may not use every level. - * @return The newly compressed data. - **/ - CompressedData *compress(Compressor::Format format, Data *rawdata, int level = -1); - CompressedData *compress(Compressor::Format format, const char *rawbytes, size_t rawsize, int level = -1); - - /** - * Decompresses existing compressed data into raw bytes. - * - * @param[in] data The compressed data to decompress. - * @param[out] decompressedsize The size in bytes of the decompressed data. - * @return The newly decompressed data (allocated with new[]). - **/ - char *decompress(CompressedData *data, size_t &decompressedsize); - - /** - * Decompresses existing compressed data into raw bytes. - * - * @param[in] format The compression format the data is in. - * @param[in] cbytes The compressed data to decompress. - * @param[in] compressedsize The size in bytes of the compressed data. - * @param[in,out] rawsize On input, the size in bytes of the original - * uncompressed data, or 0 if unknown. On return, the size in - * bytes of the newly decompressed data. - * @return The newly decompressed data (allocated with new[]). - **/ - char *decompress(Compressor::Format format, const char *cbytes, size_t compressedsize, size_t &rawsize); - - char *encode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen, size_t linelen = 0); - char *decode(EncodeFormat format, const char *src, size_t srclen, size_t &dstlen); - - static bool getConstant(const char *in, EncodeFormat &out); - static bool getConstant(EncodeFormat in, const char *&out); - static Math instance; private: Math(); - static StringMap::Entry encoderEntries[]; - static StringMap encoders; - }; // Math -inline float Math::noise(float x) const + +static inline float noise1(float x) { return SimplexNoise1234::noise(x) * 0.5f + 0.5f; } -inline float Math::noise(float x, float y) const +static inline float noise2(float x, float y) { return SimplexNoise1234::noise(x, y) * 0.5f + 0.5f; } @@ -190,12 +188,12 @@ inline float Math::noise(float x, float y) const // Perlin noise is used instead of Simplex noise in the 3D and 4D cases to avoid // patent issues. -inline float Math::noise(float x, float y, float z) const +static inline float noise3(float x, float y, float z) { return Noise1234::noise(x, y, z) * 0.5f + 0.5f; } -inline float Math::noise(float x, float y, float z, float w) const +static inline float noise4(float x, float y, float z, float w) { return Noise1234::noise(x, y, z, w) * 0.5f + 0.5f; } diff --git a/src/modules/math/wrap_Math.cpp b/src/modules/math/wrap_Math.cpp index a9bbf8cae..3094d4c8e 100644 --- a/src/modules/math/wrap_Math.cpp +++ b/src/modules/math/wrap_Math.cpp @@ -160,7 +160,7 @@ int w_triangulate(lua_State *L) if (vertices.size() == 3) triangles.push_back(Triangle(vertices[0], vertices[1], vertices[2])); else - triangles = Math::instance.triangulate(vertices); + triangles = triangulate(vertices); }); lua_createtable(L, (int) triangles.size(), 0); @@ -221,7 +221,7 @@ int w_isConvex(lua_State *L) } } - luax_pushboolean(L, Math::instance.isConvex(vertices)); + luax_pushboolean(L, isConvex(vertices)); return 1; } @@ -266,7 +266,7 @@ int w_gammaToLinear(lua_State *L) { // Alpha should always be linear. if (i < 3) - color[i] = Math::instance.gammaToLinear(color[i]); + color[i] = gammaToLinear(color[i]); lua_pushnumber(L, color[i]); } @@ -282,7 +282,7 @@ int w_linearToGamma(lua_State *L) { // Alpha should always be linear. if (i < 3) - color[i] = Math::instance.linearToGamma(color[i]); + color[i] = linearToGamma(color[i]); lua_pushnumber(L, color[i]); } @@ -302,16 +302,16 @@ int w_noise(lua_State *L) switch (nargs) { case 1: - val = Math::instance.noise(args[0]); + val = noise1(args[0]); break; case 2: - val = Math::instance.noise(args[0], args[1]); + val = noise2(args[0], args[1]); break; case 3: - val = Math::instance.noise(args[0], args[1], args[2]); + val = noise3(args[0], args[1], args[2]); break; case 4: - val = Math::instance.noise(args[0], args[1], args[2], args[3]); + val = noise4(args[0], args[1], args[2], args[3]); break; } @@ -334,12 +334,12 @@ int w_compress(lua_State *L) { size_t rawsize = 0; const char *rawbytes = luaL_checklstring(L, 1, &rawsize); - luax_catchexcept(L, [&](){ cdata = Math::instance.compress(format, rawbytes, rawsize, level); }); + luax_catchexcept(L, [&](){ cdata = compress(format, rawbytes, rawsize, level); }); } else { Data *rawdata = luax_checktype(L, 1, DATA_ID); - luax_catchexcept(L, [&](){ cdata = Math::instance.compress(format, rawdata, level); }); + luax_catchexcept(L, [&](){ cdata = compress(format, rawdata, level); }); } luax_pushtype(L, MATH_COMPRESSED_DATA_ID, cdata); @@ -355,7 +355,7 @@ int w_decompress(lua_State *L) { CompressedData *data = luax_checkcompresseddata(L, 1); rawsize = data->getDecompressedSize(); - luax_catchexcept(L, [&](){ rawbytes = Math::instance.decompress(data, rawsize); }); + luax_catchexcept(L, [&](){ rawbytes = decompress(data, rawsize); }); } else { @@ -377,7 +377,7 @@ int w_decompress(lua_State *L) else cbytes = luaL_checklstring(L, 1, &compressedsize); - luax_catchexcept(L, [&](){ rawbytes = Math::instance.decompress(format, cbytes, compressedsize, rawsize); }); + luax_catchexcept(L, [&](){ rawbytes = decompress(format, cbytes, compressedsize, rawsize); }); } lua_pushlstring(L, rawbytes, rawsize); @@ -389,8 +389,8 @@ int w_decompress(lua_State *L) int w_encode(lua_State *L) { const char *formatstr = luaL_checkstring(L, 1); - Math::EncodeFormat format; - if (!Math::getConstant(formatstr, format)) + EncodeFormat format; + if (!getConstant(formatstr, format)) return luaL_error(L, "Invalid encode format: %s", formatstr); size_t srclen = 0; @@ -409,7 +409,7 @@ int w_encode(lua_State *L) size_t dstlen = 0; char *dst = nullptr; - luax_catchexcept(L, [&](){ dst = Math::instance.encode(format, src, srclen, dstlen, linelen); }); + luax_catchexcept(L, [&](){ dst = encode(format, src, srclen, dstlen, linelen); }); if (dst != nullptr) lua_pushlstring(L, dst, dstlen); @@ -423,8 +423,8 @@ int w_encode(lua_State *L) int w_decode(lua_State *L) { const char *formatstr = luaL_checkstring(L, 1); - Math::EncodeFormat format; - if (!Math::getConstant(formatstr, format)) + EncodeFormat format; + if (!getConstant(formatstr, format)) return luaL_error(L, "Invalid decode format: %s", formatstr); size_t srclen = 0; @@ -441,7 +441,7 @@ int w_decode(lua_State *L) size_t dstlen = 0; char *dst = nullptr; - luax_catchexcept(L, [&](){ dst = Math::instance.decode(format, src, srclen, dstlen); }); + luax_catchexcept(L, [&](){ dst = decode(format, src, srclen, dstlen); }); if (dst != nullptr) lua_pushlstring(L, dst, dstlen); @@ -466,31 +466,13 @@ struct FFI_Math static FFI_Math ffifuncs = { - [](float x) -> float // noise1 - { - return Math::instance.noise(x); - }, - [](float x, float y) -> float // noise2 - { - return Math::instance.noise(x, y); - }, - [](float x, float y, float z) -> float // noise3 - { - return Math::instance.noise(x, y, z); - }, - [](float x, float y, float z, float w) -> float // noise4 - { - return Math::instance.noise(x, y, z, w); - }, + noise1, + noise2, + noise3, + noise4, - [](float c) -> float // gammaToLinear - { - return Math::instance.gammaToLinear(c); - }, - [](float c) -> float // linearToGamma - { - return Math::instance.linearToGamma(c); - } + gammaToLinear, + linearToGamma, }; // List of functions to wrap.