test: cover native material interpolation masks
Docs Deploy / Build and Deploy MkDocs (push) Successful in 34s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 34s
This commit is contained in:
1 file changed
+57
@@ -717,6 +717,10 @@ fn interpolate_coefficients(
|
|||||||
mask: u32,
|
mask: u32,
|
||||||
fraction: f32,
|
fraction: f32,
|
||||||
) -> MaterialCoefficients {
|
) -> MaterialCoefficients {
|
||||||
|
// World3D 0x3030 receives source and destination wrappers one dword before
|
||||||
|
// each D3DMATERIAL7 body. Its +4/+14/+24/+34 offsets therefore select
|
||||||
|
// parameters 4..6, 0..2, 8..10, and 12..14; +0x20 selects parameter 3.
|
||||||
|
// The other alpha/extra fields, power, and page remain from the left phase.
|
||||||
let left = left.coefficients();
|
let left = left.coefficients();
|
||||||
let right = right.coefficients();
|
let right = right.coefficients();
|
||||||
let mut output = left;
|
let mut output = left;
|
||||||
@@ -1305,6 +1309,59 @@ mod tests {
|
|||||||
assert_eq!(&wrapped.texture_raw[..4], b"LEFT");
|
assert_eq!(&wrapped.texture_raw[..4], b"LEFT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn material_animation_interpolation_masks_match_native_rebased_offsets() {
|
||||||
|
let left = phase_with_parameters(
|
||||||
|
[
|
||||||
|
10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180,
|
||||||
|
],
|
||||||
|
b"LEFT",
|
||||||
|
);
|
||||||
|
let right = phase_with_parameters(
|
||||||
|
[
|
||||||
|
70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230,
|
||||||
|
240,
|
||||||
|
],
|
||||||
|
b"RIGHT",
|
||||||
|
);
|
||||||
|
let rgb = |first: u8| [first, first + 10, first + 20].map(|value| f32::from(value) / 255.0);
|
||||||
|
let cases = [
|
||||||
|
(0, rgb(10), rgb(50), rgb(90), rgb(130), 0.4),
|
||||||
|
(1, rgb(40), rgb(50), rgb(90), rgb(130), 0.4),
|
||||||
|
(2, rgb(10), rgb(80), rgb(90), rgb(130), 0.4),
|
||||||
|
(4, rgb(10), rgb(50), rgb(120), rgb(130), 0.4),
|
||||||
|
(8, rgb(10), rgb(50), rgb(90), rgb(160), 0.4),
|
||||||
|
(16, rgb(10), rgb(50), rgb(90), rgb(130), 0.7),
|
||||||
|
(0x1f, rgb(40), rgb(80), rgb(120), rgb(160), 0.7),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (mask, additive, directional, specular, extra, opacity) in cases {
|
||||||
|
let output = interpolate_coefficients(&left, &right, mask, 0.5);
|
||||||
|
for (actual, expected) in [
|
||||||
|
(output.additive_rgb, additive),
|
||||||
|
(output.directional_rgb, directional),
|
||||||
|
(output.specular_rgb, specular),
|
||||||
|
(output.extra_rgb, extra),
|
||||||
|
] {
|
||||||
|
for channel in 0..3 {
|
||||||
|
assert!(
|
||||||
|
(actual[channel] - expected[channel]).abs() < 1e-6,
|
||||||
|
"mask {mask:#x}, channel {channel}: got {}, expected {}",
|
||||||
|
actual[channel],
|
||||||
|
expected[channel]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!((output.opacity - opacity).abs() < 1e-6, "mask {mask:#x}");
|
||||||
|
assert_eq!(output.directional_extra, 80.0 / 255.0);
|
||||||
|
assert_eq!(output.specular_extra, 120.0 / 255.0);
|
||||||
|
assert_eq!(output.extra_alpha, 160.0 / 255.0);
|
||||||
|
assert_eq!(output.power, 170);
|
||||||
|
assert_eq!(output.page_index, -76);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn material_ping_pong_reverses_local_time_and_clamp_holds_last_phase() {
|
fn material_ping_pong_reverses_local_time_and_clamp_holds_last_phase() {
|
||||||
let phases = vec![
|
let phases = vec![
|
||||||
|
|||||||
Reference in new issue
Block a user