Skip to content

Commit

Permalink
Adhere to lints.
Browse files Browse the repository at this point in the history
  • Loading branch information
n3vu0r committed Aug 6, 2023
1 parent 6b0e50f commit 32f3f70
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 16 deletions.
18 changes: 9 additions & 9 deletions src/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ impl<N: Copy + RealField> Clamp<N> for Bound<N> {
fn target(&self, frame: &Frame<N>) -> Option<Plane<N>> {
let target = self.transform.inverse() * frame.target();
let axes = [Vector3::x_axis(), Vector3::y_axis(), Vector3::z_axis()];
for axis in 0..2 {
let min_plane = Plane::new(axes[axis], self.min_target[axis]);
for (distance, axis) in axes.into_iter().enumerate() {
let min_plane = Plane::new(axis, self.min_target[distance]);
if min_plane.distance_from(&target) > self.hysteresis {
return Some(min_plane);
}
let max_plane = Plane::new(axes[axis], self.max_target[axis]);
let max_plane = Plane::new(axis, self.max_target[distance]);
if max_plane.distance_from(&target) < -self.hysteresis {
return Some(max_plane);
}
Expand All @@ -90,12 +90,12 @@ impl<N: Copy + RealField> Clamp<N> for Bound<N> {
}
let eye = self.transform.inverse() * frame.eye();
let axes = [Vector3::x_axis(), Vector3::y_axis(), Vector3::z_axis()];
for axis in 0..2 {
let min_plane = Plane::new(axes[axis], self.min_eye[axis]);
for (distance, axis) in axes.into_iter().enumerate() {
let min_plane = Plane::new(axis, self.min_eye[distance]);
if min_plane.distance_from(&eye) > self.hysteresis {
return Some(min_plane);
}
let max_plane = Plane::new(axes[axis], self.max_eye[axis]);
let max_plane = Plane::new(axis, self.max_eye[distance]);
if max_plane.distance_from(&eye) < -self.hysteresis {
return Some(max_plane);
}
Expand All @@ -111,12 +111,12 @@ impl<N: Copy + RealField> Clamp<N> for Bound<N> {
);
let up = yaw * frame.yaw_axis();
let axes = [Vector3::x_axis(), Vector3::y_axis(), Vector3::z_axis()];
for axis in 0..2 {
let min_plane = Plane::new(yaw.inverse() * axes[axis], self.min_up[axis]);
for (distance, axis) in axes.into_iter().enumerate() {
let min_plane = Plane::new(yaw.inverse() * axis, self.min_up[distance]);
if min_plane.distance_from(&Point3::from(up.into_inner())) > self.hysteresis {
return Some(min_plane);
}
let max_plane = Plane::new(yaw.inverse() * axes[axis], self.max_up[axis]);
let max_plane = Plane::new(yaw.inverse() * axis, self.max_up[distance]);
if max_plane.distance_from(&Point3::from(up.into_inner())) < -self.hysteresis {
return Some(max_plane);
}
Expand Down
15 changes: 10 additions & 5 deletions src/clamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,31 @@ pub trait Clamp<N: Copy + RealField>: Send + Sync + Debug + 'static {
/// Measure to break out of validation loop as last resort. Default is `100`. Round boundary
/// conditions require more loops where as flat ones should stop with the 3rd validation
/// (i.e., a corner) for each validated position (e.g., target, eye).
#[must_use]
fn loops(&self) -> usize {
100
}

/// Exceeded boundary plane for target position in world space.
///
/// Must return `None` if target position satisfies all boundary conditions.
#[must_use]
fn target(&self, frame: &Frame<N>) -> Option<Plane<N>>;
/// Exceeded boundary plane for eye position in world space.
///
/// Must return `None` if eye position satisfies all boundary conditions.
#[must_use]
fn eye(&self, frame: &Frame<N>) -> Option<Plane<N>>;
/// Exceeded boundary plane for up position in world space.
///
/// Must return `None` if up position satisfies all boundary conditions.
#[must_use]
fn up(&self, frame: &Frame<N>) -> Option<Plane<N>>;

/// Computes clamped [`Delta`] wrt abstract user boundary conditions of [`Frame`] and [`Scope`].
///
/// Returns `None` if [`Delta`] satisfies all boundary conditions.
#[must_use]
fn compute(
&self,
frame: &Frame<N>,
Expand Down Expand Up @@ -70,7 +75,7 @@ pub trait Clamp<N: Copy + RealField>: Send + Sync + Debug + 'static {
// Radius of spherical cap.
let radius = (height * (distance * (N::one() + N::one()) - height)).sqrt();
// New clamped target position in spherical cap space.
let new_target = (plane.project_point(&frame.target()) - center)
let new_target = (plane.project_point(frame.target()) - center)
.normalize()
.scale(radius);
// New clamped target position in world space.
Expand Down Expand Up @@ -131,7 +136,7 @@ pub trait Clamp<N: Copy + RealField>: Send + Sync + Debug + 'static {
if let Some(plane) = self.eye(&frame) {
bound = true;
// Center of spherical cap in world space.
let center = plane.project_point(&target);
let center = plane.project_point(target);
// Height of spherical cap.
let height = distance - (center - target).norm();
// Radius of spherical cap.
Expand Down Expand Up @@ -179,11 +184,11 @@ pub trait Clamp<N: Copy + RealField>: Send + Sync + Debug + 'static {
let mut bound = false;
if let Some(plane) = self.target(&frame) {
bound = true;
let new_target = plane.project_point(&frame.target());
let new_target = plane.project_point(frame.target());
let vec = old_rot_inverse * (new_target - old_target);
min_delta = Delta::Slide { vec };
}
let frame = min_delta.transform(&old_frame);
let frame = min_delta.transform(old_frame);
if let Some(plane) = self.eye(&frame) {
bound = true;
let new_eye = plane.project_point(&frame.eye());
Expand Down Expand Up @@ -219,8 +224,8 @@ pub trait Clamp<N: Copy + RealField>: Send + Sync + Debug + 'static {
let new_zat = old_zat * rat;
if new_zat < min_zat {
bound = true;
let _rat = min_zat / old_zat;
// TODO Implement grind.
let _rat = min_zat / old_zat;
min_delta = Delta::Frame;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub enum Delta<N: Copy + RealField> {

impl<N: Copy + RealField> Delta<N> {
/// Transforms from initial to final frame.
#[must_use]
pub fn transform(&self, frame: &Frame<N>) -> Frame<N> {
let mut frame = frame.clone();
match self {
Expand Down Expand Up @@ -130,6 +131,7 @@ impl<N: Copy + RealField> Delta<N> {
/// Assumes `other` to be similar (e.g., a clamped `self`).
///
/// Returns `None` if transforms are of different variants and neither is [`Self::Frame`].
#[must_use]
pub fn minimum(&self, other: &Self) -> Option<Self> {
match (self, other) {
(Self::Frame, _) => Some(other.clone()),
Expand Down Expand Up @@ -209,6 +211,7 @@ impl<N: Copy + RealField> Delta<N> {
}
}
/// Casts components to another type, e.g., between [`f32`] and [`f64`].
#[must_use]
pub fn cast<M: Copy + RealField>(self) -> Delta<M>
where
N: SubsetOf<M>,
Expand Down
3 changes: 3 additions & 0 deletions src/first.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,17 @@ impl<N: Copy + RealField> First<N> {
self.ray = None;
}
/// Whether a yaw axis has been captured.
#[must_use]
pub const fn enabled(&self) -> bool {
self.ray.is_some()
}
/// Captured yaw axis.
#[must_use]
pub const fn yaw_axis(&self) -> Option<&Unit<Vector3<N>>> {
self.ray.as_ref()
}
/// Casts components to another type, e.g., between [`f32`] and [`f64`].
#[must_use]
pub fn cast<M: Copy + RealField>(self) -> First<M>
where
N: SubsetOf<M>,
Expand Down
2 changes: 2 additions & 0 deletions src/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,15 @@ impl<N: Copy + RealField> Fixed<N> {
}
}
/// Underlying quantity.
#[must_use]
pub const fn into_inner(self) -> N {
match self {
Self::Hor(fov) | Self::Ver(fov) => fov,
Self::Upp(upp) => upp,
}
}
/// Casts components to another type, e.g., between [`f32`] and [`f64`].
#[must_use]
pub fn cast<M: Copy + RealField>(self) -> Fixed<M>
where
N: SubsetOf<M>,
Expand Down
14 changes: 14 additions & 0 deletions src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Frame<N: Copy + RealField> {

impl<N: Copy + RealField> Frame<N> {
/// Sets eye position inclusive its roll attitude and target position in world space.
#[must_use]
pub fn look_at(target: Point3<N>, eye: &Point3<N>, up: &Vector3<N>) -> Self {
let dir = target - eye;
Self {
Expand All @@ -29,6 +30,7 @@ impl<N: Copy + RealField> Frame<N> {
}
}
/// Eye position in world space.
#[must_use]
pub fn eye(&self) -> Point3<N> {
self.pos + self.rot * Vector3::z_axis().into_inner() * self.zat
}
Expand All @@ -37,6 +39,7 @@ impl<N: Copy + RealField> Frame<N> {
*self = Self::look_at(self.pos, eye, up);
}
/// Target position in world space.
#[must_use]
pub const fn target(&self) -> &Point3<N> {
&self.pos
}
Expand All @@ -47,6 +50,7 @@ impl<N: Copy + RealField> Frame<N> {
self.zat = (self.pos - eye).norm();
}
/// Distance between eye and target.
#[must_use]
pub const fn distance(&self) -> N {
self.zat
}
Expand Down Expand Up @@ -106,28 +110,34 @@ impl<N: Copy + RealField> Frame<N> {
}
/// Positive x-axis in camera space pointing from left to right.
#[allow(clippy::unused_self)]
#[must_use]
pub fn local_pitch_axis(&self) -> Unit<Vector3<N>> {
Vector3::x_axis()
}
/// Positive y-axis in camera space pointing from bottom to top.
#[allow(clippy::unused_self)]
#[must_use]
pub fn local_yaw_axis(&self) -> Unit<Vector3<N>> {
Vector3::y_axis()
}
/// Positive z-axis in camera space pointing from back to front.
#[allow(clippy::unused_self)]
#[must_use]
pub fn local_roll_axis(&self) -> Unit<Vector3<N>> {
Vector3::z_axis()
}
/// Positive x-axis in world space pointing from left to right.
#[must_use]
pub fn pitch_axis(&self) -> Unit<Vector3<N>> {
self.rot * self.local_pitch_axis()
}
/// Positive y-axis in world space pointing from bottom to top.
#[must_use]
pub fn yaw_axis(&self) -> Unit<Vector3<N>> {
self.rot * self.local_yaw_axis()
}
/// Positive z-axis in world space pointing from back to front.
#[must_use]
pub fn roll_axis(&self) -> Unit<Vector3<N>> {
self.rot * self.local_roll_axis()
}
Expand All @@ -144,6 +154,7 @@ impl<N: Copy + RealField> Frame<N> {
/// * `t`: The interpolation parameter between 0 and 1.
/// * `epsilon`: The value below which the sinus of the angle separating both quaternion
/// must be to return `None`.
#[must_use]
pub fn try_lerp_slerp(&self, other: &Self, t: N, epsilon: N) -> Option<Self> {
Some(Self {
pos: self.pos.lerp(&other.pos, t),
Expand All @@ -156,6 +167,7 @@ impl<N: Copy + RealField> Frame<N> {
self.rot.renormalize()
}
/// View transformation from camera to world space.
#[must_use]
pub fn view(&self) -> Isometry3<N> {
Isometry3::from_parts(
// Eye position in world space with origin in camera space.
Expand All @@ -167,6 +179,7 @@ impl<N: Copy + RealField> Frame<N> {
/// Inverse view transformation from world to camera space.
///
/// Uses less computations than [`Self::view()`]`.inverse()`.
#[must_use]
pub fn inverse_view(&self) -> Isometry3<N> {
// Eye rotation from world to camera space around target.
let rot = self.rot.inverse();
Expand All @@ -176,6 +189,7 @@ impl<N: Copy + RealField> Frame<N> {
Isometry3::from_parts((-eye.coords).into(), rot)
}
/// Casts components to another type, e.g., between [`f32`] and [`f64`].
#[must_use]
pub fn cast<M: Copy + RealField>(self) -> Frame<M>
where
N: SubsetOf<M>,
Expand Down
17 changes: 17 additions & 0 deletions src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct Image<N: Copy + RealField> {

impl<N: Copy + RealField> Image<N> {
/// Computes initial transformations from frame, scope, and screen's width and height.
#[must_use]
pub fn new(frame: &Frame<N>, scope: &Scope<N>, max: Point2<N>) -> Self {
let mut image = Self {
pos: Point2::origin(),
Expand Down Expand Up @@ -94,6 +95,7 @@ impl<N: Copy + RealField> Image<N> {
self.compute_inv = compute_inv;
}
/// Current position in screen space of hovering input or pointing device.
#[must_use]
pub const fn pos(&self) -> &Point2<N> {
&self.pos
}
Expand All @@ -102,6 +104,7 @@ impl<N: Copy + RealField> Image<N> {
self.pos = pos;
}
/// Maximum position in screen space as screen's width and height.
#[must_use]
pub const fn max(&self) -> &Point2<N> {
&self.max
}
Expand All @@ -114,14 +117,17 @@ impl<N: Copy + RealField> Image<N> {
self.max = max;
}
/// Cached unit per pixel on focus plane to scale/project positions/vectors onto focus plane.
#[must_use]
pub const fn upp(&self) -> N {
self.upp
}
/// Cached view isometry.
#[must_use]
pub const fn view_isometry(&self) -> &Isometry3<N> {
&self.view_iso
}
/// Cached view matrix.
#[must_use]
pub const fn view(&self) -> &Matrix4<N> {
&self.view_mat
}
Expand All @@ -131,6 +137,7 @@ impl<N: Copy + RealField> Image<N> {
self.view_mat = self.view_iso.to_homogeneous();
}
/// Cached projection matrix.
#[must_use]
pub const fn projection(&self) -> &Matrix4<N> {
&self.proj_mat
}
Expand All @@ -141,6 +148,7 @@ impl<N: Copy + RealField> Image<N> {
self.proj_mat = mat;
}
/// Cached projection view matrix.
#[must_use]
pub const fn transformation(&self) -> &Matrix4<N> {
&self.proj_view_mat
}
Expand All @@ -149,6 +157,7 @@ impl<N: Copy + RealField> Image<N> {
self.proj_view_mat = self.proj_mat * self.view_mat;
}
/// Cached inverse projection view matrix.
#[must_use]
pub const fn inverse_transformation(&self) -> &Matrix4<N> {
&self.proj_view_inv
}
Expand All @@ -163,14 +172,17 @@ impl<N: Copy + RealField> Image<N> {
inv.is_some()
}
/// Clamps position in screen space wrt its maximum in screen space.
#[must_use]
pub fn clamp_pos_wrt_max(pos: &Point2<N>, max: &Point2<N>) -> Point2<N> {
Point2::new(pos.x.clamp(N::zero(), max.x), pos.y.clamp(N::zero(), max.y))
}
/// Clamps position in screen space.
#[must_use]
pub fn clamp_pos(&self, pos: &Point2<N>) -> Point2<N> {
Self::clamp_pos_wrt_max(pos, &self.max)
}
/// Transforms position and its maximum from screen to camera space wrt its maximum.
#[must_use]
pub fn transform_pos_and_max_wrt_max(
pos: &Point2<N>,
max: &Point2<N>,
Expand All @@ -179,14 +191,17 @@ impl<N: Copy + RealField> Image<N> {
(Point2::new(pos.x - max.x, max.y - pos.y), max)
}
/// Transforms position from screen to camera space.
#[must_use]
pub fn transform_pos(&self, pos: &Point2<N>) -> Point2<N> {
Self::transform_pos_and_max_wrt_max(pos, &self.max).0
}
/// Transforms vector from screen to camera space.
#[must_use]
pub fn transform_vec(pos: &Vector2<N>) -> Vector2<N> {
Vector2::new(pos.x, -pos.y)
}
/// Transforms position from screen to camera space and projects it onto focus plane.
#[must_use]
pub fn project_pos(&self, pos: &Point2<N>) -> Point3<N> {
self.transform_pos(pos)
.coords
Expand All @@ -195,10 +210,12 @@ impl<N: Copy + RealField> Image<N> {
.into()
}
/// Transforms vector from screen to camera space and projects it onto focus plane.
#[must_use]
pub fn project_vec(&self, vec: &Vector2<N>) -> Vector3<N> {
Self::transform_vec(vec).scale(self.upp).push(N::zero())
}
/// Casts components to another type, e.g., between [`f32`] and [`f64`].
#[must_use]
pub fn cast<M: Copy + RealField>(self) -> Image<M>
where
N: SubsetOf<M>,
Expand Down
Loading

0 comments on commit 32f3f70

Please sign in to comment.