Quat Quat::operator /(float scalar) const { assume(!EqualAbs(scalar, 0.f)); #ifdef MATH_AUTOMATIC_SSE return div_ps(q, set1_ps(scalar)); #else return *this * (1.f / scalar); #endif }
/** Implementation based on the math in the book Watt, Policarpo. 3D Games: Real-time rendering and Software Technology, pp. 383-386. */ Quat MUST_USE_RESULT Quat::Slerp(const Quat &q2, float t) const { ///\todo SSE. assume(0.f <= t && t <= 1.f); assume(IsNormalized()); assume(q2.IsNormalized()); float angle = this->Dot(q2); float sign = 1.f; // Multiply by a sign of +/-1 to guarantee we rotate the shorter arc. if (angle < 0.f) { angle = -angle; sign = -1.f; } float a; float b; if (angle <= 0.97f) // perform spherical linear interpolation. { angle = Acos(angle); // After this, angle is in the range pi/2 -> 0 as the original angle variable ranged from 0 -> 1. float angleT = t*angle; #if defined(MATH_AUTOMATIC_SSE) && defined(MATH_SSE) // Compute three sines in one go with SSE. simd4f s = set_ps(0.f, angleT, angle - angleT, angle); s = sin_ps(s); simd4f denom = shuffle1_ps(s, _MM_SHUFFLE(0, 0, 0, 0)); s = div_ps(s, denom); a = s4f_y(s); b = s4f_z(s); #else float s[3] = { Sin(angle), Sin(angle - angleT), Sin(angleT) }; float c = 1.f / s[0]; a = s[1] * c; b = s[2] * c; #endif } else // If angle is close to taking the denominator to zero, resort to linear interpolation (and normalization). { a = 1.f - t; b = t; } return (*this * (a * sign) + q2 * b).Normalized(); }
float3x4 float3x4::operator /(float scalar) const { assume(!EqualAbs(scalar, 0)); #ifdef MATH_SIMD float3x4 r; simd4f s = set1_ps(scalar); simd4f one = set1_ps(1.f); s = div_ps(one, s); r.row[0] = mul_ps(row[0], s); r.row[1] = mul_ps(row[1], s); r.row[2] = mul_ps(row[2], s); #else float3x4 r = *this; r /= scalar; #endif return r; }
float3x4 &float3x4::operator /=(float scalar) { assume(!EqualAbs(scalar, 0)); #ifdef MATH_SIMD simd4f s = set1_ps(scalar); simd4f one = set1_ps(1.f); s = div_ps(one, s); row[0] = mul_ps(row[0], s); row[1] = mul_ps(row[1], s); row[2] = mul_ps(row[2], s); #else float invScalar = 1.f / scalar; for(int y = 0; y < Rows; ++y) for(int x = 0; x < Cols; ++x) v[y][x] *= invScalar; #endif return *this; }