Set the scene transform by linear iterpolation of the eye transforms

This commit is contained in:
Alan Jeffrey 2019-06-07 12:02:30 -05:00
parent 005e7d3835
commit a507e1955e
2 changed files with 24 additions and 2 deletions

View File

@ -25,6 +25,7 @@ use clap::{App, Arg};
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::basic::rect::RectF;
use pathfinder_geometry::basic::transform2d::Transform2DF;
use pathfinder_geometry::basic::transform3d::Transform3DF;
use pathfinder_geometry::color::ColorU;
use pathfinder_gl::GLDevice;
use pathfinder_gpu::Device;
@ -53,6 +54,9 @@ const CAMERA_SCALE_SPEED_2D: f32 = 6.0;
// How much the scene is scaled when a zoom button is clicked.
const CAMERA_ZOOM_AMOUNT_2D: f32 = 0.1;
// Half of the eye separation distance.
const DEFAULT_EYE_OFFSET: f32 = 0.025;
const LIGHT_BG_COLOR: ColorU = ColorU {
r: 248,
g: 248,
@ -328,9 +332,18 @@ impl<W> DemoApp<W> where W: Window {
..
} = self.camera
{
// TODO: really we should lerp all the eye transforms to get the new scene transform
*scene_transform = new_eye_transforms[0];
*eye_transforms = new_eye_transforms;
// Calculate the new scene transform by lerp'ing the eye transforms.
*scene_transform = eye_transforms[0];
for (index, eye_transform) in eye_transforms.iter().enumerate().skip(1) {
let weight = 1.0 / (index + 1) as f32;
scene_transform.perspective.transform = scene_transform.perspective.transform.lerp(weight, &eye_transform.perspective.transform);
scene_transform.modelview_to_eye = scene_transform.modelview_to_eye.lerp(weight, &eye_transform.modelview_to_eye);
}
// TODO: calculate the eye offset from the eye transforms?
let z_offset = -DEFAULT_EYE_OFFSET * scene_transform.perspective.transform.c0.x();
scene_transform.modelview_to_eye = scene_transform.modelview_to_eye
.pre_mul(&Transform3DF::from_translation(0.0, 0.0, z_offset));
}
}
Event::KeyDown(Keycode::Alphanumeric(b'w')) => {

View File

@ -176,6 +176,15 @@ impl Transform3DF {
)
}
/// Linearly interpolate between transforms
pub fn lerp(&self, weight: f32, other: &Transform3DF) -> Transform3DF {
let c0 = self.c0 * F32x4::splat(weight) + other.c0 * F32x4::splat(1.0 - weight);
let c1 = self.c1 * F32x4::splat(weight) + other.c1 * F32x4::splat(1.0 - weight);
let c2 = self.c2 * F32x4::splat(weight) + other.c2 * F32x4::splat(1.0 - weight);
let c3 = self.c3 * F32x4::splat(weight) + other.c3 * F32x4::splat(1.0 - weight);
Transform3DF { c0, c1, c2, c3 }
}
/// Just like `gluPerspective()`.
#[inline]
pub fn from_perspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) -> Transform3DF {