mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
8609d33dec
To allow MatrixDouble to be a drop-in replacement for gfxMatrix, it needs to accept the "double" versions of Point, Rect, and Size. This patch does that by adding some extra typedefs inside BaseMatrix to abstract over that. It also moves some function implementations into the .h file as they don't need specialization. I left some function implementations in the Matrix.cpp file: - Rotation, because it is specialized for Float and Double, since it uses sinf/cosf vs sin/cos in the two implementations. - The Matrix4x4 multiplication operator overload, because if I put it inside the BaseMatrix class declaration Matrix4x4 isn't defined yet and the compiler doesn't like it. MozReview-Commit-ID: K56dZjJhXWS --HG-- extra : rebase_source : d009151942811a725ee6bf854238073e59665d5c
124 lines
3.2 KiB
C++
124 lines
3.2 KiB
C++
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "Matrix.h"
|
|
#include "Quaternion.h"
|
|
#include "Tools.h"
|
|
#include <algorithm>
|
|
#include <ostream>
|
|
#include <math.h>
|
|
#include <float.h> // for FLT_EPSILON
|
|
|
|
#include "mozilla/FloatingPoint.h" // for UnspecifiedNaN
|
|
|
|
using namespace std;
|
|
|
|
|
|
namespace mozilla {
|
|
namespace gfx {
|
|
|
|
/* Force small values to zero. We do this to avoid having sin(360deg)
|
|
* evaluate to a tiny but nonzero value.
|
|
*/
|
|
double
|
|
FlushToZero(double aVal)
|
|
{
|
|
// XXX Is double precision really necessary here
|
|
if (-FLT_EPSILON < aVal && aVal < FLT_EPSILON) {
|
|
return 0.0f;
|
|
} else {
|
|
return aVal;
|
|
}
|
|
}
|
|
|
|
/* Computes tan(aTheta). For values of aTheta such that tan(aTheta) is
|
|
* undefined or very large, SafeTangent returns a manageably large value
|
|
* of the correct sign.
|
|
*/
|
|
double
|
|
SafeTangent(double aTheta)
|
|
{
|
|
// XXX Is double precision really necessary here
|
|
const double kEpsilon = 0.0001;
|
|
|
|
/* tan(theta) = sin(theta)/cos(theta); problems arise when
|
|
* cos(theta) is too close to zero. Limit cos(theta) to the
|
|
* range [-1, -epsilon] U [epsilon, 1].
|
|
*/
|
|
|
|
double sinTheta = sin(aTheta);
|
|
double cosTheta = cos(aTheta);
|
|
|
|
if (cosTheta >= 0 && cosTheta < kEpsilon) {
|
|
cosTheta = kEpsilon;
|
|
} else if (cosTheta < 0 && cosTheta >= -kEpsilon) {
|
|
cosTheta = -kEpsilon;
|
|
}
|
|
return FlushToZero(sinTheta / cosTheta);
|
|
}
|
|
|
|
template<> Matrix
|
|
Matrix::Rotation(Float aAngle)
|
|
{
|
|
Matrix newMatrix;
|
|
|
|
Float s = sinf(aAngle);
|
|
Float c = cosf(aAngle);
|
|
|
|
newMatrix._11 = c;
|
|
newMatrix._12 = s;
|
|
newMatrix._21 = -s;
|
|
newMatrix._22 = c;
|
|
|
|
return newMatrix;
|
|
}
|
|
|
|
template<> MatrixDouble
|
|
MatrixDouble::Rotation(Double aAngle)
|
|
{
|
|
MatrixDouble newMatrix;
|
|
|
|
Double s = sin(aAngle);
|
|
Double c = cos(aAngle);
|
|
|
|
newMatrix._11 = c;
|
|
newMatrix._12 = s;
|
|
newMatrix._21 = -s;
|
|
newMatrix._22 = c;
|
|
|
|
return newMatrix;
|
|
}
|
|
|
|
template<> Matrix4x4
|
|
MatrixDouble::operator*(const Matrix4x4& aMatrix) const
|
|
{
|
|
Matrix4x4 resultMatrix;
|
|
|
|
resultMatrix._11 = this->_11 * aMatrix._11 + this->_12 * aMatrix._21;
|
|
resultMatrix._12 = this->_11 * aMatrix._12 + this->_12 * aMatrix._22;
|
|
resultMatrix._13 = this->_11 * aMatrix._13 + this->_12 * aMatrix._23;
|
|
resultMatrix._14 = this->_11 * aMatrix._14 + this->_12 * aMatrix._24;
|
|
|
|
resultMatrix._21 = this->_21 * aMatrix._11 + this->_22 * aMatrix._21;
|
|
resultMatrix._22 = this->_21 * aMatrix._12 + this->_22 * aMatrix._22;
|
|
resultMatrix._23 = this->_21 * aMatrix._13 + this->_22 * aMatrix._23;
|
|
resultMatrix._24 = this->_21 * aMatrix._14 + this->_22 * aMatrix._24;
|
|
|
|
resultMatrix._31 = aMatrix._31;
|
|
resultMatrix._32 = aMatrix._32;
|
|
resultMatrix._33 = aMatrix._33;
|
|
resultMatrix._34 = aMatrix._34;
|
|
|
|
resultMatrix._41 = this->_31 * aMatrix._11 + this->_32 * aMatrix._21 + aMatrix._41;
|
|
resultMatrix._42 = this->_31 * aMatrix._12 + this->_32 * aMatrix._22 + aMatrix._42;
|
|
resultMatrix._43 = this->_31 * aMatrix._13 + this->_32 * aMatrix._23 + aMatrix._43;
|
|
resultMatrix._44 = this->_31 * aMatrix._14 + this->_32 * aMatrix._24 + aMatrix._44;
|
|
|
|
return resultMatrix;
|
|
}
|
|
|
|
} // namespace gfx
|
|
} // namespace mozilla
|