mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
style: Cleanup and add references to Quaternion::animate.
No functional change, but I did this while searching for the bug. Bug: 1459403 Reviewed-by: hiro MozReview-Commit-ID: KsJxFoYaOq1
This commit is contained in:
parent
99d4e7b65c
commit
6ddb04a483
1 changed files with 34 additions and 23 deletions
|
@ -1820,12 +1820,16 @@ impl Animate for Quaternion {
|
||||||
use std::f64;
|
use std::f64;
|
||||||
|
|
||||||
let (this_weight, other_weight) = procedure.weights();
|
let (this_weight, other_weight) = procedure.weights();
|
||||||
debug_assert!((this_weight + other_weight - 1.0f64).abs() <= f64::EPSILON ||
|
debug_assert!(
|
||||||
other_weight == 1.0f64 || other_weight == 0.0f64,
|
(this_weight + other_weight - 1.0f64).abs() <= f64::EPSILON ||
|
||||||
"animate should only be used for interpolating or accumulating transforms");
|
other_weight == 1.0f64 || other_weight == 0.0f64,
|
||||||
|
"animate should only be used for interpolating or accumulating transforms"
|
||||||
|
);
|
||||||
|
|
||||||
// We take a specialized code path for accumulation (where other_weight is 1)
|
// We take a specialized code path for accumulation (where other_weight
|
||||||
if other_weight == 1.0 {
|
// is 1).
|
||||||
|
if let Procedure::Accumulate { .. } = procedure {
|
||||||
|
debug_assert_eq!(other_weight, 1.0);
|
||||||
if this_weight == 0.0 {
|
if this_weight == 0.0 {
|
||||||
return Ok(*other);
|
return Ok(*other);
|
||||||
}
|
}
|
||||||
|
@ -1856,32 +1860,39 @@ impl Animate for Quaternion {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut product = self.0 * other.0 +
|
// Straight from gfxQuaternion::Slerp.
|
||||||
self.1 * other.1 +
|
//
|
||||||
self.2 * other.2 +
|
// Dot product, clamped between -1 and 1.
|
||||||
self.3 * other.3;
|
let dot =
|
||||||
|
(self.0 * other.0 +
|
||||||
|
self.1 * other.1 +
|
||||||
|
self.2 * other.2 +
|
||||||
|
self.3 * other.3)
|
||||||
|
.min(1.0).max(-1.0);
|
||||||
|
|
||||||
// Clamp product to -1.0 <= product <= 1.0
|
if dot == 1.0 {
|
||||||
product = product.min(1.0);
|
|
||||||
product = product.max(-1.0);
|
|
||||||
|
|
||||||
if product == 1.0 {
|
|
||||||
return Ok(*self);
|
return Ok(*self);
|
||||||
}
|
}
|
||||||
|
|
||||||
let theta = product.acos();
|
let theta = dot.acos();
|
||||||
let w = (other_weight * theta).sin() * 1.0 / (1.0 - product * product).sqrt();
|
let rsintheta = 1.0 / (1.0 - dot * dot).sqrt();
|
||||||
|
|
||||||
let mut a = *self;
|
let right_weight = (other_weight * theta).sin() * rsintheta;
|
||||||
let mut b = *other;
|
let left_weight = (other_weight * theta).cos() - dot * right_weight;
|
||||||
let mut result = Quaternion(0., 0., 0., 0.,);
|
|
||||||
|
let mut left = *self;
|
||||||
|
let mut right = *other;
|
||||||
% for i in range(4):
|
% for i in range(4):
|
||||||
a.${i} *= (other_weight * theta).cos() - product * w;
|
left.${i} *= left_weight;
|
||||||
b.${i} *= w;
|
right.${i} *= right_weight;
|
||||||
result.${i} = a.${i} + b.${i};
|
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
Ok(result)
|
Ok(Quaternion(
|
||||||
|
left.0 + right.0,
|
||||||
|
left.1 + right.1,
|
||||||
|
left.2 + right.2,
|
||||||
|
left.3 + right.3,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue