[cpp] Replaced usages of math.h with MathUtil.

This commit is contained in:
badlogic 2018-02-20 15:32:31 +01:00
parent bef01b8e89
commit 1c21542148
9 changed files with 134 additions and 91 deletions

View File

@ -33,8 +33,8 @@
#include <spine/SpineObject.h>
#include <math.h>
#include <float.h>
#include <string.h>
#define SPINE_PI 3.1415927f
#define SPINE_PI_2 (SPINE_PI * 2)
@ -50,39 +50,20 @@
#define MAX(a, b) ((((a) > (b)) ? (a) : (b)))
#define MIN(a, b) ((((a) < (b)) ? (a) : (b)))
namespace Spine {
template <typename T>
int sign(T val) {
return (T(0) < val) - (val < T(0));
}
inline bool areFloatsPracticallyEqual(float A, float B, float maxDiff = 0.0000000000000001f, float maxRelDiff = FLT_EPSILON) {
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float diff = fabs(A - B);
if (diff <= maxDiff) {
return true;
}
A = fabs(A);
B = fabs(B);
float largest = (B > A) ? B : A;
if (diff <= largest * maxRelDiff) {
return true;
}
return false;
}
inline float clamp(float x, float lower, float upper) {
return fminf(upper, fmaxf(x, lower));
}
class MathUtil : public SpineObject {
public:
MathUtil();
static int sign(float val);
static bool areFloatsPracticallyEqual(float A, float B, float maxDiff = 0.0000000000000001f, float maxRelDiff = FLT_EPSILON);
static float clamp(float x, float lower, float upper);
static float abs(float v);
/// Returns the sine in radians from a lookup table.
static float sin(float radians);
@ -99,6 +80,14 @@ namespace Spine {
/// Returns atan2 in radians, faster but less accurate than Math.Atan2. Average error of 0.00231 radians (0.1323
/// degrees), largest error of 0.00488 radians (0.2796 degrees).
static float atan2(float y, float x);
static float acos(float v);
static float sqrt(float v);
static float fmod(float a, float b);
static bool isNan(float v);
private:
static float SIN_TABLE[SIN_COUNT];

View File

@ -37,7 +37,6 @@
#include <spine/ContainerUtil.h>
#include <assert.h>
#include <math.h> /* fmod */
namespace Spine {
Animation::Animation(const String& name, Vector<Timeline*>& timelines, float duration) :
@ -53,9 +52,9 @@ namespace Spine {
void Animation::apply(Skeleton& skeleton, float lastTime, float time, bool loop, Vector<Event*>* pEvents, float alpha, MixPose pose, MixDirection direction) {
if (loop && _duration != 0) {
time = fmod(time, _duration);
time = MathUtil::fmod(time, _duration);
if (lastTime > 0) {
lastTime = fmod(lastTime, _duration);
lastTime = MathUtil::fmod(lastTime, _duration);
}
}

View File

@ -90,7 +90,7 @@ namespace Spine {
return _animationStart;
}
return fmodf(_trackTime, duration) + _animationStart;
return MathUtil::fmod(_trackTime, duration) + _animationStart;
}
return MIN(_trackTime + _animationStart, _animationEnd);
@ -705,17 +705,17 @@ namespace Spine {
bool current = diff > 0, dir = lastTotal >= 0;
// Detect cross at 0 (not 180).
if (sign(lastDiff) != sign(diff) && fabs(lastDiff) <= 90) {
if (MathUtil::sign(lastDiff) != MathUtil::sign(diff) && MathUtil::abs(lastDiff) <= 90) {
// A cross after a 360 rotation is a loop.
if (fabs(lastTotal) > 180) {
lastTotal += 360 * sign(lastTotal);
if (MathUtil::abs(lastTotal) > 180) {
lastTotal += 360 * MathUtil::sign(lastTotal);
}
dir = current;
}
total = diff + lastTotal - fmod(lastTotal, 360); // Store loops as part of lastTotal.
total = diff + lastTotal - MathUtil::fmod(lastTotal, 360); // Store loops as part of lastTotal.
if (dir != current) {
total += 360 * sign(lastTotal);
total += 360 * MathUtil::sign(lastTotal);
}
timelinesRotation[i] = total;
}
@ -847,7 +847,7 @@ namespace Spine {
void AnimationState::queueEvents(TrackEntry* entry, float animationTime) {
float animationStart = entry->_animationStart, animationEnd = entry->_animationEnd;
float duration = animationEnd - animationStart;
float trackLastWrapped = fmodf(entry->_trackLast, duration);
float trackLastWrapped = MathUtil::fmod(entry->_trackLast, duration);
// Queue events before complete.
int i = 0, n = static_cast<int>(_events.size());
@ -864,7 +864,7 @@ namespace Spine {
}
// Queue complete if completed a loop iteration or the animation.
if (entry->_loop ? (trackLastWrapped > fmod(entry->_trackTime, duration)) : (animationTime >= animationEnd && entry->_animationLast < animationEnd)) {
if (entry->_loop ? (trackLastWrapped > MathUtil::fmod(entry->_trackTime, duration)) : (animationTime >= animationEnd && entry->_animationLast < animationEnd)) {
_queue->complete(entry);
}

View File

@ -161,7 +161,7 @@ namespace Spine {
case TransformMode_NoRotationOrReflection: {
float s = pa * pa + pc * pc, prx;
if (s > 0.0001f) {
s = fabs(pa * pd - pb * pc) / s;
s = MathUtil::abs(pa * pd - pb * pc) / s;
pb = pc * s;
pd = pa * s;
prx = MathUtil::atan2(pc, pa) * RadDeg;
@ -191,14 +191,14 @@ namespace Spine {
float sin = MathUtil::sinDeg(rotation);
float za = pa * cos + pb * sin;
float zc = pc * cos + pd * sin;
float s = sqrt(za * za + zc * zc);
float s = MathUtil::sqrt(za * za + zc * zc);
if (s > 0.00001f) {
s = 1 / s;
}
za *= s;
zc *= s;
s = sqrt(za * za + zc * zc);
s = MathUtil::sqrt(za * za + zc * zc);
float r = SPINE_PI / 2 + MathUtil::atan2(zc, za);
float zb = MathUtil::cos(r) * s;
float zd = MathUtil::sin(r) * s;
@ -510,11 +510,11 @@ namespace Spine {
}
float Bone::getWorldScaleX() {
return sqrt(_a * _a + _c * _c);
return MathUtil::sqrt(_a * _a + _c * _c);
}
float Bone::getWorldScaleY() {
return sqrt(_b * _b + _d * _d);
return MathUtil::sqrt(_b * _b + _d * _d);
}
void Bone::updateAppliedTransform() {
@ -524,8 +524,8 @@ namespace Spine {
_ax = _worldX;
_ay = _worldY;
_arotation = MathUtil::atan2(_c, _a) * RadDeg;
_ascaleX = sqrt(_a * _a + _c * _c);
_ascaleY = sqrt(_b * _b + _d * _d);
_ascaleX = MathUtil::sqrt(_a * _a + _c * _c);
_ascaleY = MathUtil::sqrt(_b * _b + _d * _d);
_ashearX = 0;
_ashearY = MathUtil::atan2(_a * _b + _c * _d, _a * _d - _b * _c) * RadDeg;
@ -555,7 +555,7 @@ namespace Spine {
float rd = id * _d - ic * _b;
_ashearX = 0;
_ascaleX = sqrt(ra * ra + rc * rc);
_ascaleX = MathUtil::sqrt(ra * ra + rc * rc);
if (_ascaleX > 0.0001f) {
float det = ra * rd - rb * rc;
@ -565,7 +565,7 @@ namespace Spine {
}
else {
_ascaleX = 0;
_ascaleY = sqrt(rb * rb + rd * rd);
_ascaleY = MathUtil::sqrt(rb * rb + rd * rd);
_ashearY = 0;
_arotation = 90 - MathUtil::atan2(rd, rb) * RadDeg;
}

View File

@ -85,7 +85,7 @@ namespace Spine {
}
float CurveTimeline::getCurvePercent(int frameIndex, float percent) {
percent = clamp(percent, 0, 1);
percent = MathUtil::clamp(percent, 0, 1);
int i = frameIndex * BEZIER_SIZE;
float type = _curves[i];

View File

@ -51,7 +51,7 @@ namespace Spine {
float id = 1 / (p._a * p._d - p._b * p._c);
float x = targetX - p._worldX, y = targetY - p._worldY;
float tx = (x * p._d - y * p._b) * id - bone._ax, ty = (y * p._a - x * p._c) * id - bone._ay;
float rotationIK = atan2(ty, tx) * RadDeg - bone._ashearX - bone._arotation;
float rotationIK = MathUtil::atan2(ty, tx) * RadDeg - bone._ashearX - bone._arotation;
if (bone._ascaleX < 0) {
rotationIK += 180;
@ -68,7 +68,7 @@ namespace Spine {
}
void IkConstraint::apply(Bone& parent, Bone& child, float targetX, float targetY, int bendDir, float alpha) {
if (areFloatsPracticallyEqual(alpha, 0)) {
if (MathUtil::areFloatsPracticallyEqual(alpha, 0)) {
child.updateWorldTransform();
return;
@ -121,7 +121,7 @@ namespace Spine {
float c = parent._c;
float d = parent._d;
bool u = fabs(psx - psy) <= 0.0001f;
bool u = MathUtil::abs(psx - psy) <= 0.0001f;
if (!u) {
cy = 0;
cwx = a * cx + parent._worldX;
@ -146,7 +146,7 @@ namespace Spine {
x = cwx - pp._worldX;
y = cwy - pp._worldY;
float dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
float l1 = sqrt(dx * dx + dy * dy), l2 = child._data.getLength() * csx, a1, a2;
float l1 = MathUtil::sqrt(dx * dx + dy * dy), l2 = child._data.getLength() * csx, a1, a2;
if (u) {
l2 *= psx;
float cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
@ -157,30 +157,30 @@ namespace Spine {
cos = 1;
}
a2 = acos(cos) * bendDir;
a2 = MathUtil::acos(cos) * bendDir;
a = l1 + l2 * cos;
b = l2 * sin(a2);
a1 = atan2(ty * a - tx * b, tx * a + ty * b);
b = l2 * MathUtil::sin(a2);
a1 = MathUtil::atan2(ty * a - tx * b, tx * a + ty * b);
}
else {
a = psx * l2;
b = psy * l2;
float aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = atan2(ty, tx);
float aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = MathUtil::atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb;
float c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c;
if (d >= 0) {
float q = sqrt(d);
float q = MathUtil::sqrt(d);
if (c1 < 0) q = -q;
q = -(c1 + q) / 2;
float r0 = q / c2, r1 = c / q;
float r = fabs(r0) < fabs(r1) ? r0 : r1;
float r = MathUtil::abs(r0) < MathUtil::abs(r1) ? r0 : r1;
if (r * r <= dd) {
y = sqrt(dd - r * r) * bendDir;
a1 = ta - atan2(y, r);
a2 = atan2(y / psy, (r - l1) / psx);
y = MathUtil::sqrt(dd - r * r) * bendDir;
a1 = ta - MathUtil::atan2(y, r);
a2 = MathUtil::atan2(y / psy, (r - l1) / psx);
float os = atan2(cy, cx) * s2;
float os = MathUtil::atan2(cy, cx) * s2;
float rotation = parent._arotation;
a1 = (a1 - os) * RadDeg + os1 - rotation;
if (a1 > 180) {
@ -211,9 +211,9 @@ namespace Spine {
float maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
c = -a * l1 / (aa - bb);
if (c >= -1 && c <= 1) {
c = acos(c);
x = a * cos(c) + l1;
y = b * (float)sin(c);
c = MathUtil::acos(c);
x = a * MathUtil::cos(c) + l1;
y = b * (float)MathUtil::sin(c);
d = x * x + y * y;
if (d < minDist) {
@ -232,11 +232,11 @@ namespace Spine {
}
if (dd <= (minDist + maxDist) / 2) {
a1 = ta - atan2(minY * bendDir, minX);
a1 = ta - MathUtil::atan2(minY * bendDir, minX);
a2 = minAngle * bendDir;
}
else {
a1 = ta - atan2(maxY * bendDir, maxX);
a1 = ta - MathUtil::atan2(maxY * bendDir, maxX);
a2 = maxAngle * bendDir;
}
}

View File

@ -29,6 +29,7 @@
*****************************************************************************/
#include <spine/MathUtil.h>
#include <math.h>
namespace Spine {
float MathUtil::SIN_TABLE[SIN_COUNT] = {0.0f};
@ -42,6 +43,34 @@ namespace Spine {
SIN_TABLE[i * DegToIndex & SIN_MASK] = sin(i * DegRad);
}
}
int MathUtil::sign(float val) {
return (0 < val) - (val < 0);
}
bool MathUtil::areFloatsPracticallyEqual(float A, float B, float maxDiff, float maxRelDiff) {
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float diff = fabs(A - B);
if (diff <= maxDiff) {
return true;
}
A = fabs(A);
B = fabs(B);
float largest = (B > A) ? B : A;
if (diff <= largest * maxRelDiff) {
return true;
}
return false;
}
float MathUtil::clamp(float x, float lower, float upper) {
return fminf(upper, fmaxf(x, lower));
}
/// Returns the sine in radians from a lookup table.
float MathUtil::sin(float radians) {
@ -93,4 +122,30 @@ namespace Spine {
return y < 0.0f ? atan - SPINE_PI : atan;
}
float MathUtil::acos(float v) {
return ::acos(v);
}
float MathUtil::sqrt(float v) {
return ::sqrt(v);
}
float MathUtil::fmod(float a, float b) {
return ::fmod(a, b);
}
float MathUtil::abs(float v) {
return ::fabs(v);
}
/* Need to pass 0 as an argument, so VC++ doesn't error with C2124 */
static bool _isNan(float value, float zero) {
float _nan = (float)0.0 / zero;
return 0 == memcmp((void*)&value, (void*)&_nan, sizeof(value));
}
bool MathUtil::isNan(float v) {
return _isNan(v, 0);
}
}

View File

@ -118,7 +118,7 @@ namespace Spine {
else {
float x = setupLength * bone._a;
float y = setupLength * bone._c;
float length = sqrt(x * x + y * y);
float length = MathUtil::sqrt(x * x + y * y);
if (scale) {
_lengths[i] = length;
}
@ -159,7 +159,7 @@ namespace Spine {
if (scale) {
float length = _lengths[i];
if (length >= PathConstraint::EPSILON) {
float s = (sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
float s = (MathUtil::sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
bone._a *= s;
bone._c *= s;
}
@ -298,7 +298,7 @@ namespace Spine {
float p = position;
if (closed) {
p = fmod(p, pathLength);
p = MathUtil::fmod(p, pathLength);
if (p < 0) {
p += pathLength;
@ -398,18 +398,18 @@ namespace Spine {
ddfy = tmpy * 2 + dddfy;
dfx = (cx1 - x1) * 0.75f + tmpx + dddfx * 0.16666667f;
dfy = (cy1 - y1) * 0.75f + tmpy + dddfy * 0.16666667f;
pathLength += sqrt(dfx * dfx + dfy * dfy);
pathLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
dfx += ddfx;
dfy += ddfy;
ddfx += dddfx;
ddfy += dddfy;
pathLength += sqrt(dfx * dfx + dfy * dfy);
pathLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
dfx += ddfx;
dfy += ddfy;
pathLength += sqrt(dfx * dfx + dfy * dfy);
pathLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
dfx += ddfx + dddfx;
dfy += ddfy + dddfy;
pathLength += sqrt(dfx * dfx + dfy * dfy);
pathLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
_curves[i] = pathLength;
x1 = x2;
y1 = y2;
@ -432,7 +432,7 @@ namespace Spine {
float p = position;
if (closed) {
p = fmod(p, pathLength);
p = MathUtil::fmod(p, pathLength);
if (p < 0) {
p += pathLength;
@ -485,23 +485,23 @@ namespace Spine {
ddfy = tmpy * 2 + dddfy;
dfx = (cx1 - x1) * 0.3f + tmpx + dddfx * 0.16666667f;
dfy = (cy1 - y1) * 0.3f + tmpy + dddfy * 0.16666667f;
curveLength = sqrt(dfx * dfx + dfy * dfy);
curveLength = MathUtil::sqrt(dfx * dfx + dfy * dfy);
_segments[0] = curveLength;
for (ii = 1; ii < 8; ii++) {
dfx += ddfx;
dfy += ddfy;
ddfx += dddfx;
ddfy += dddfy;
curveLength += sqrt(dfx * dfx + dfy * dfy);
curveLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
_segments[ii] = curveLength;
}
dfx += ddfx;
dfy += ddfy;
curveLength += sqrt(dfx * dfx + dfy * dfy);
curveLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
_segments[8] = curveLength;
dfx += ddfx + dddfx;
dfy += ddfy + dddfy;
curveLength += sqrt(dfx * dfx + dfy * dfy);
curveLength += MathUtil::sqrt(dfx * dfx + dfy * dfy);
_segments[9] = curveLength;
segment = 0;
}
@ -553,7 +553,7 @@ namespace Spine {
}
void PathConstraint::addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, Vector<float>& output, int o, bool tangents) {
if (p < EPSILON || isnan(p)) {
if (p < EPSILON || MathUtil::isNan(p)) {
p = EPSILON;
}
@ -563,7 +563,7 @@ namespace Spine {
output[o] = x;
output[o + 1] = y;
if (tangents) {
output[o + 2] = atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
output[o + 2] = MathUtil::atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
}
}
}

View File

@ -171,17 +171,17 @@ namespace Spine {
}
if (scaleMix > 0) {
float s = sqrt(bone._a * bone._a + bone._c * bone._c);
float s = MathUtil::sqrt(bone._a * bone._a + bone._c * bone._c);
if (s > 0.00001f) {
s = (s + (sqrt(ta * ta + tc * tc) - s + _data._offsetScaleX) * scaleMix) / s;
s = (s + (MathUtil::sqrt(ta * ta + tc * tc) - s + _data._offsetScaleX) * scaleMix) / s;
}
bone._a *= s;
bone._c *= s;
s = sqrt(bone._b * bone._b + bone._d * bone._d);
s = MathUtil::sqrt(bone._b * bone._b + bone._d * bone._d);
if (s > 0.00001f) {
s = (s + (sqrt(tb * tb + td * td) - s + _data._offsetScaleY) * scaleMix) / s;
s = (s + (MathUtil::sqrt(tb * tb + td * td) - s + _data._offsetScaleY) * scaleMix) / s;
}
bone._b *= s;
bone._d *= s;
@ -200,7 +200,7 @@ namespace Spine {
}
r = by + (r + offsetShearY) * shearMix;
float s = sqrt(b * b + d * d);
float s = MathUtil::sqrt(b * b + d * d);
bone._b = MathUtil::cos(r) * s;
bone._d = MathUtil::sin(r) * s;
modified = true;
@ -252,10 +252,10 @@ namespace Spine {
}
if (scaleMix > 0) {
float s = (sqrt(ta * ta + tc * tc) - 1 + _data._offsetScaleX) * scaleMix + 1;
float s = (MathUtil::sqrt(ta * ta + tc * tc) - 1 + _data._offsetScaleX) * scaleMix + 1;
bone._a *= s;
bone._c *= s;
s = (sqrt(tb * tb + td * td) - 1 + _data._offsetScaleY) * scaleMix + 1;
s = (MathUtil::sqrt(tb * tb + td * td) - 1 + _data._offsetScaleY) * scaleMix + 1;
bone._b *= s;
bone._d *= s;
modified = true;
@ -272,7 +272,7 @@ namespace Spine {
float b = bone._b, d = bone._d;
r = MathUtil::atan2(d, b) + (r - SPINE_PI / 2 + offsetShearY) * shearMix;
float s = sqrt(b * b + d * d);
float s = MathUtil::sqrt(b * b + d * d);
bone._b = MathUtil::cos(r) * s;
bone._d = MathUtil::sin(r) * s;
modified = true;