float MathUtils::atan2f(float y, float x) { // MSDN docs appear to state that Infinity is in the domain for atan2f, but // that does not appear to be true. So implement the whole mess here. // Easy cases are handled by the libc function. if (isFiniteAndNonzerof(y) && isFiniteAndNonzerof(x)) return ::atan2f(y, x); if (isNaNf(x)) return x; if (isNaNf(y)) return y; if (isInfinitef(y)) { if (!isInfinitef(x)) return (y > 0 ? (PI_f / 2) : -(PI_f / 2)); float r = (x > 0 ? (PI_f / 4) : (3 * PI_f / 4)); return (y > 0 ? r : -r); } else if (y != 0) { if (x == 0) return (y > 0 ? (PI_f / 2) : -(PI_f / 2)); assert(isInfinite(x)); float r = (x > 0 ? 0.0f : PI_f); return (y > 0 ? r : -r); } else // y == 0 { int32_t zx = isZerof(x); int32_t zy = isZerof(y); float r = (x > 0 || zx == 1) ? 0 : PI_f; return (zy > 0) ? r : -r; } }
void matrixx_t::load(const matrixf_t& rhs) { GLfixed* xp = m; GLfloat const* fp = rhs.elements(); unsigned int i = 16; do { const GLfloat f = *fp++; *xp++ = isZerof(f) ? 0 : gglFloatToFixed(f); } while (--i); }
void matrixf_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z) { matrixf_t rotation; GLfloat* r = rotation.m; GLfloat c, s; r[3] = 0; r[7] = 0; r[11]= 0; r[12]= 0; r[13]= 0; r[14]= 0; r[15]= 1; a *= GLfloat(M_PI / 180.0f); sincosf(a, &s, &c); if (isOnef(x) && isZerof(y) && isZerof(z)) { r[5] = c; r[10]= c; r[6] = s; r[9] = -s; r[1] = 0; r[2] = 0; r[4] = 0; r[8] = 0; r[0] = 1; } else if (isZerof(x) && isOnef(y) && isZerof(z)) { r[0] = c; r[10]= c; r[8] = s; r[2] = -s; r[1] = 0; r[4] = 0; r[6] = 0; r[9] = 0; r[5] = 1; } else if (isZerof(x) && isZerof(y) && isOnef(z)) { r[0] = c; r[5] = c; r[1] = s; r[4] = -s; r[2] = 0; r[6] = 0; r[8] = 0; r[9] = 0; r[10]= 1; } else { const GLfloat len = sqrtf(x*x + y*y + z*z); if (!isOnef(len)) { const GLfloat recipLen = reciprocalf(len); x *= recipLen; y *= recipLen; z *= recipLen; } const GLfloat nc = 1.0f - c; const GLfloat xy = x * y; const GLfloat yz = y * z; const GLfloat zx = z * x; const GLfloat xs = x * s; const GLfloat ys = y * s; const GLfloat zs = z * s; r[ 0] = x*x*nc + c; r[ 4] = xy*nc - zs; r[ 8] = zx*nc + ys; r[ 1] = xy*nc + zs; r[ 5] = y*y*nc + c; r[ 9] = yz*nc - xs; r[ 2] = zx*nc - ys; r[ 6] = yz*nc + xs; r[10] = z*z*nc + c; } multiply(rotation); }