зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1467277 - Avoid getting zero normalized vector of rotate3d when setting a rotate matrix. r=nical
For example, if we set a transform to rotate3d(0, 0, 1e50, 45deg), the expected normalized rotate axis is (0, 0, 1). However, the length is larger than the maximum of float, so the actual value is (0/inf, 0/inf, 1e50/inf) == (0, 0, 0). Therefore, we scale the vector before doing normalization to avoid getting a zero vector. MozReview-Commit-ID: 5LUDWD4RuNj --HG-- extra : rebase_source : eb82f0b3979bf6ea3cd11b643ebb30a49edc24f8
This commit is contained in:
Родитель
f0bf583292
Коммит
ffa1da7545
|
@ -87,10 +87,10 @@ struct BasePoint3D {
|
|||
}
|
||||
|
||||
Sub& operator/=(T aScale) {
|
||||
x /= aScale;
|
||||
y /= aScale;
|
||||
z /= aScale;
|
||||
return *static_cast<Sub*>(this);
|
||||
x /= aScale;
|
||||
y /= aScale;
|
||||
z /= aScale;
|
||||
return *static_cast<Sub*>(this);
|
||||
}
|
||||
|
||||
Sub operator-() const {
|
||||
|
@ -98,22 +98,34 @@ struct BasePoint3D {
|
|||
}
|
||||
|
||||
Sub CrossProduct(const Sub& aPoint) const {
|
||||
return Sub(y * aPoint.z - aPoint.y * z,
|
||||
z * aPoint.x - aPoint.z * x,
|
||||
x * aPoint.y - aPoint.x * y);
|
||||
return Sub(y * aPoint.z - aPoint.y * z,
|
||||
z * aPoint.x - aPoint.z * x,
|
||||
x * aPoint.y - aPoint.x * y);
|
||||
}
|
||||
|
||||
T DotProduct(const Sub& aPoint) const {
|
||||
return x * aPoint.x + y * aPoint.y + z * aPoint.z;
|
||||
return x * aPoint.x + y * aPoint.y + z * aPoint.z;
|
||||
}
|
||||
|
||||
T Length() const {
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
// Invalid for points with distance from origin of 0.
|
||||
void Normalize() {
|
||||
*this /= Length();
|
||||
*this /= Length();
|
||||
}
|
||||
|
||||
void RobustNormalize() {
|
||||
// If the distance is infinite, we scale it by 1/(the maximum value of T)
|
||||
// before doing normalization, so we can avoid getting a zero point.
|
||||
T length = Length();
|
||||
if (mozilla::IsInfinite(length)) {
|
||||
*this /= std::numeric_limits<T>::max();
|
||||
length = Length();
|
||||
}
|
||||
|
||||
*this /= length;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const BasePoint3D<T, Sub>& aPoint) {
|
||||
|
|
|
@ -1650,7 +1650,7 @@ public:
|
|||
if (!vector.Length()) {
|
||||
return;
|
||||
}
|
||||
vector.Normalize();
|
||||
vector.RobustNormalize();
|
||||
|
||||
double x = vector.x;
|
||||
double y = vector.y;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="transform: rotate3d(1e50, 0, 0, 45deg); width: 100px; height: 100px;">
|
||||
Test Text
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -32,6 +32,7 @@ fuzzy-if(winWidget,143,689) fuzzy-if(OSX,224,924) fuzzy-if(winWidget,154,644) ra
|
|||
fuzzy-if(skiaContent,1,4) == matrix3d-1a.html matrix3d-1-ref.html
|
||||
== matrix3d-2a.html matrix3d-2-ref.html
|
||||
== rotate3d-1a.html rotatex-1-ref.html
|
||||
== 1467277-1.html rotatex-1-ref.html
|
||||
fuzzy-if(webrender,0-1,0-6) == rotate3d-2a.html rotatey-1-ref.html
|
||||
!= backface-visibility-1a.html about:blank
|
||||
== backface-visibility-1b.html about:blank
|
||||
|
|
Загрузка…
Ссылка в новой задаче