2019-02-04 23:20:32 -05:00
|
|
|
// pathfinder/geometry/src/basic/point.rs
|
2019-01-11 18:24:13 -05:00
|
|
|
//
|
|
|
|
// Copyright © 2019 The Pathfinder Project Developers.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
//! A SIMD-optimized point type.
|
|
|
|
|
2019-06-25 17:43:13 -04:00
|
|
|
use pathfinder_simd::default::{F32x2, F32x4, I32x2};
|
2019-02-13 19:05:28 -05:00
|
|
|
use std::ops::{Add, AddAssign, Mul, Neg, Sub};
|
2019-01-11 18:24:13 -05:00
|
|
|
|
2019-02-05 13:55:01 -05:00
|
|
|
/// 2D points with 32-bit floating point coordinates.
|
2019-01-12 20:13:58 -05:00
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub struct Vector2F(pub F32x2);
|
2019-01-11 18:24:13 -05:00
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Vector2F {
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn new(x: f32, y: f32) -> Vector2F {
|
2019-06-25 17:43:13 -04:00
|
|
|
Vector2F(F32x2::new(x, y))
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn splat(value: f32) -> Vector2F {
|
2019-06-25 17:43:13 -04:00
|
|
|
Vector2F(F32x2::splat(value))
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
|
2019-01-15 22:15:33 -05:00
|
|
|
#[inline]
|
2019-12-07 14:51:47 -05:00
|
|
|
pub fn to_3d(self) -> Vector3F {
|
|
|
|
Vector3F(self.0.to_f32x4().concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 0.0)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn to_4d(self) -> Vector4F {
|
2019-06-25 17:43:13 -04:00
|
|
|
Vector4F(self.0.to_f32x4().concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 1.0)))
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
|
|
|
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn x(self) -> f32 {
|
2019-01-11 18:24:13 -05:00
|
|
|
self.0[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn y(self) -> f32 {
|
2019-01-11 18:24:13 -05:00
|
|
|
self.0[1]
|
|
|
|
}
|
|
|
|
|
2019-01-28 15:57:15 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn set_x(&mut self, x: f32) {
|
|
|
|
self.0[0] = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn set_y(&mut self, y: f32) {
|
|
|
|
self.0[1] = y;
|
|
|
|
}
|
|
|
|
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn min(self, other: Vector2F) -> Vector2F {
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector2F(self.0.min(other.0))
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn max(self, other: Vector2F) -> Vector2F {
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector2F(self.0.max(other.0))
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
2019-01-23 00:40:43 -05:00
|
|
|
|
2019-02-04 19:04:13 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn clamp(self, min_val: Vector2F, max_val: Vector2F) -> Vector2F {
|
2019-02-04 19:04:13 -05:00
|
|
|
self.max(min_val).min(max_val)
|
|
|
|
}
|
|
|
|
|
2019-01-23 00:40:43 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn det(self, other: Vector2F) -> f32 {
|
2019-01-23 00:40:43 -05:00
|
|
|
self.x() * other.y() - self.y() * other.x()
|
|
|
|
}
|
2019-01-28 15:57:15 -05:00
|
|
|
|
2019-02-18 16:42:30 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn dot(self, other: Vector2F) -> f32 {
|
2019-02-18 16:42:30 -05:00
|
|
|
let xy = self.0 * other.0;
|
|
|
|
xy.x() + xy.y()
|
|
|
|
}
|
|
|
|
|
2019-01-28 15:57:15 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn scale(self, x: f32) -> Vector2F {
|
|
|
|
Vector2F(self.0 * F32x2::splat(x))
|
2019-01-28 15:57:15 -05:00
|
|
|
}
|
2019-02-05 13:55:01 -05:00
|
|
|
|
2019-02-05 23:10:20 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn scale_xy(self, factors: Vector2F) -> Vector2F {
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector2F(self.0 * factors.0)
|
2019-02-05 23:10:20 -05:00
|
|
|
}
|
|
|
|
|
2019-02-05 13:55:01 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn floor(self) -> Vector2F {
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector2F(self.0.floor())
|
2019-02-05 13:55:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn ceil(self) -> Vector2F {
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector2F(self.0.ceil())
|
2019-02-05 13:55:01 -05:00
|
|
|
}
|
2019-02-05 23:10:20 -05:00
|
|
|
|
2019-02-20 21:27:18 -05:00
|
|
|
/// Treats this point as a vector and calculates its squared length.
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn square_length(self) -> f32 {
|
2019-02-20 21:27:18 -05:00
|
|
|
let squared = self.0 * self.0;
|
|
|
|
squared[0] + squared[1]
|
|
|
|
}
|
|
|
|
|
2019-02-05 23:10:20 -05:00
|
|
|
/// Treats this point as a vector and calculates its length.
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn length(self) -> f32 {
|
2019-02-20 21:27:18 -05:00
|
|
|
f32::sqrt(self.square_length())
|
2019-02-05 23:10:20 -05:00
|
|
|
}
|
2019-02-06 16:12:53 -05:00
|
|
|
|
|
|
|
/// Treats this point as a vector and normalizes it.
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn normalize(self) -> Vector2F {
|
2019-02-06 16:12:53 -05:00
|
|
|
self.scale(1.0 / self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Swaps y and x.
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn yx(self) -> Vector2F {
|
|
|
|
Vector2F(self.0.yx())
|
2019-02-06 16:12:53 -05:00
|
|
|
}
|
2019-02-06 21:09:37 -05:00
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn is_zero(self) -> bool {
|
|
|
|
self == Vector2F::default()
|
2019-02-06 21:09:37 -05:00
|
|
|
}
|
2019-02-20 19:21:58 -05:00
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn lerp(self, other: Vector2F, t: f32) -> Vector2F {
|
|
|
|
self + (other - self).scale(t)
|
2019-02-20 19:21:58 -05:00
|
|
|
}
|
2019-03-14 22:13:27 -04:00
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn to_i32(self) -> Vector2I {
|
|
|
|
Vector2I(self.0.to_i32x2())
|
2019-03-14 22:13:27 -04:00
|
|
|
}
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl PartialEq for Vector2F {
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn eq(&self, other: &Vector2F) -> bool {
|
2019-06-25 17:43:13 -04:00
|
|
|
self.0.packed_eq(other.0).is_all_ones()
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Add<Vector2F> for Vector2F {
|
|
|
|
type Output = Vector2F;
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn add(self, other: Vector2F) -> Vector2F {
|
|
|
|
Vector2F(self.0 + other.0)
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Sub<Vector2F> for Vector2F {
|
|
|
|
type Output = Vector2F;
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn sub(self, other: Vector2F) -> Vector2F {
|
|
|
|
Vector2F(self.0 - other.0)
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Mul<Vector2F> for Vector2F {
|
|
|
|
type Output = Vector2F;
|
2019-01-11 18:24:13 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn mul(self, other: Vector2F) -> Vector2F {
|
|
|
|
Vector2F(self.0 * other.0)
|
2019-01-11 18:24:13 -05:00
|
|
|
}
|
|
|
|
}
|
2019-01-15 22:15:33 -05:00
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Neg for Vector2F {
|
|
|
|
type Output = Vector2F;
|
2019-02-13 19:05:28 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn neg(self) -> Vector2F {
|
|
|
|
Vector2F(-self.0)
|
2019-02-13 19:05:28 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-05 13:55:01 -05:00
|
|
|
/// 2D points with 32-bit signed integer coordinates.
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub struct Vector2I(pub I32x2);
|
2019-02-05 13:55:01 -05:00
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Vector2I {
|
2019-02-05 13:55:01 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn new(x: i32, y: i32) -> Vector2I {
|
2019-06-25 17:43:13 -04:00
|
|
|
Vector2I(I32x2::new(x, y))
|
2019-02-05 13:55:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn splat(value: i32) -> Vector2I {
|
2019-06-25 17:43:13 -04:00
|
|
|
Vector2I(I32x2::splat(value))
|
2019-02-05 13:55:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn x(self) -> i32 {
|
2019-02-05 13:55:01 -05:00
|
|
|
self.0[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn y(self) -> i32 {
|
2019-02-05 13:55:01 -05:00
|
|
|
self.0[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn set_x(&mut self, x: i32) {
|
|
|
|
self.0[0] = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn set_y(&mut self, y: i32) {
|
|
|
|
self.0[1] = y;
|
|
|
|
}
|
2019-02-07 19:38:24 -05:00
|
|
|
|
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn scale(self, factor: i32) -> Vector2I {
|
|
|
|
Vector2I(self.0 * I32x2::splat(factor))
|
2019-02-07 19:38:24 -05:00
|
|
|
}
|
2019-02-12 17:49:24 -05:00
|
|
|
|
2019-03-22 17:28:18 -04:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn scale_xy(self, factors: Vector2I) -> Vector2I {
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector2I(self.0 * factors.0)
|
2019-03-22 17:28:18 -04:00
|
|
|
}
|
|
|
|
|
2019-02-12 17:49:24 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn to_f32(self) -> Vector2F {
|
|
|
|
Vector2F(self.0.to_f32x2())
|
2019-02-12 17:49:24 -05:00
|
|
|
}
|
2019-02-05 13:55:01 -05:00
|
|
|
}
|
2019-01-15 22:15:33 -05:00
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Add<Vector2I> for Vector2I {
|
|
|
|
type Output = Vector2I;
|
2019-02-07 17:07:05 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn add(self, other: Vector2I) -> Vector2I {
|
|
|
|
Vector2I(self.0 + other.0)
|
2019-02-07 17:07:05 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl AddAssign<Vector2I> for Vector2I {
|
2019-03-06 13:47:52 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn add_assign(&mut self, other: Vector2I) {
|
2019-03-06 13:47:52 -05:00
|
|
|
self.0 += other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Sub<Vector2I> for Vector2I {
|
|
|
|
type Output = Vector2I;
|
2019-02-07 19:38:24 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn sub(self, other: Vector2I) -> Vector2I {
|
|
|
|
Vector2I(self.0 - other.0)
|
2019-02-07 19:38:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl PartialEq for Vector2I {
|
2019-02-20 21:27:18 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn eq(&self, other: &Vector2I) -> bool {
|
2019-06-25 17:43:13 -04:00
|
|
|
self.0.packed_eq(other.0).is_all_ones()
|
2019-02-20 21:27:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 14:51:47 -05:00
|
|
|
/// 3D points.
|
|
|
|
///
|
|
|
|
/// The w value in the SIMD vector is always 0.0.
|
|
|
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
|
|
|
pub struct Vector3F(pub F32x4);
|
|
|
|
|
|
|
|
impl Vector3F {
|
|
|
|
#[inline]
|
|
|
|
pub fn new(x: f32, y: f32, z: f32) -> Vector3F {
|
|
|
|
Vector3F(F32x4::new(x, y, z, 0.0))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn splat(x: f32) -> Vector3F {
|
|
|
|
let mut vector = F32x4::splat(x);
|
|
|
|
vector.set_w(0.0);
|
|
|
|
Vector3F(vector)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Truncates this vector to 2D.
|
|
|
|
#[inline]
|
|
|
|
pub fn to_2d(self) -> Vector2F {
|
|
|
|
Vector2F(self.0.xy())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts this vector to an equivalent 3D homogeneous one with a w component of 1.0.
|
|
|
|
#[inline]
|
|
|
|
pub fn to_4d(self) -> Vector4F {
|
|
|
|
let mut vector = self.0;
|
|
|
|
vector.set_w(1.0);
|
|
|
|
Vector4F(vector)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn cross(self, other: Vector3F) -> Vector3F {
|
|
|
|
Vector3F(self.0.yzxw() * other.0.zxyw() - self.0.zxyw() * other.0.yzxw())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn square_length(self) -> f32 {
|
|
|
|
let squared = self.0 * self.0;
|
|
|
|
squared[0] + squared[1] + squared[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn length(self) -> f32 {
|
|
|
|
f32::sqrt(self.square_length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn normalize(self) -> Vector3F {
|
|
|
|
Vector3F(self.0 * F32x4::splat(1.0 / self.length()))
|
|
|
|
}
|
2019-12-18 18:19:42 -05:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn x(self) -> f32 {
|
|
|
|
self.0[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn y(self) -> f32 {
|
|
|
|
self.0[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn z(self) -> f32 {
|
|
|
|
self.0[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn scale(self, factor: f32) -> Vector3F {
|
|
|
|
Vector3F(self.0 * F32x4::splat(factor))
|
|
|
|
}
|
2019-12-07 14:51:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Add<Vector3F> for Vector3F {
|
|
|
|
type Output = Vector3F;
|
|
|
|
#[inline]
|
|
|
|
fn add(self, other: Vector3F) -> Vector3F {
|
|
|
|
Vector3F(self.0 + other.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AddAssign for Vector3F {
|
|
|
|
#[inline]
|
|
|
|
fn add_assign(&mut self, other: Vector3F) {
|
|
|
|
self.0 += other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-18 18:19:42 -05:00
|
|
|
impl Neg for Vector3F {
|
|
|
|
type Output = Vector3F;
|
|
|
|
#[inline]
|
|
|
|
fn neg(self) -> Vector3F {
|
|
|
|
Vector3F(self.0 * F32x4::new(-1.0, -1.0, -1.0, 0.0))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 14:51:47 -05:00
|
|
|
impl Sub<Vector3F> for Vector3F {
|
|
|
|
type Output = Vector3F;
|
|
|
|
#[inline]
|
|
|
|
fn sub(self, other: Vector3F) -> Vector3F {
|
|
|
|
Vector3F(self.0 - other.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-05 13:55:01 -05:00
|
|
|
/// 3D homogeneous points.
|
2019-02-14 21:53:02 -05:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub struct Vector4F(pub F32x4);
|
2019-01-15 22:15:33 -05:00
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Vector4F {
|
2019-01-15 22:15:33 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn new(x: f32, y: f32, z: f32, w: f32) -> Vector4F {
|
|
|
|
Vector4F(F32x4::new(x, y, z, w))
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn splat(value: f32) -> Vector4F {
|
|
|
|
Vector4F(F32x4::splat(value))
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn to_2d(self) -> Vector2F {
|
2019-12-07 14:51:47 -05:00
|
|
|
self.to_3d().to_2d()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Performs perspective division to convert this vector to 3D.
|
|
|
|
#[inline]
|
|
|
|
pub fn to_3d(self) -> Vector3F {
|
|
|
|
let mut vector = self.0 * F32x4::splat(1.0 / self.w());
|
|
|
|
vector.set_w(0.0);
|
|
|
|
Vector3F(vector)
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn x(self) -> f32 {
|
|
|
|
self.0[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn y(self) -> f32 {
|
|
|
|
self.0[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn z(self) -> f32 {
|
|
|
|
self.0[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn w(self) -> f32 {
|
|
|
|
self.0[3]
|
|
|
|
}
|
|
|
|
|
2019-02-08 18:16:53 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn scale(self, x: f32) -> Vector4F {
|
2019-02-08 18:16:53 -05:00
|
|
|
let mut factors = F32x4::splat(x);
|
|
|
|
factors[3] = 1.0;
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector4F(self.0 * factors)
|
2019-02-08 18:16:53 -05:00
|
|
|
}
|
|
|
|
|
2019-01-17 11:45:23 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn set_x(&mut self, x: f32) {
|
|
|
|
self.0[0] = x
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn set_y(&mut self, y: f32) {
|
|
|
|
self.0[1] = y
|
|
|
|
}
|
|
|
|
|
2019-01-16 23:41:05 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn set_z(&mut self, z: f32) {
|
|
|
|
self.0[2] = z
|
|
|
|
}
|
|
|
|
|
2019-01-17 11:45:23 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn set_w(&mut self, w: f32) {
|
|
|
|
self.0[3] = w
|
|
|
|
}
|
|
|
|
|
2019-01-25 17:28:53 -05:00
|
|
|
#[inline]
|
2019-06-25 17:43:13 -04:00
|
|
|
pub fn approx_eq(self, other: Vector4F, epsilon: f32) -> bool {
|
2019-01-25 17:28:53 -05:00
|
|
|
self.0.approx_eq(other.0, epsilon)
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
2019-01-29 18:44:31 -05:00
|
|
|
|
|
|
|
/// Checks to see whether this *homogeneous* coordinate equals zero.
|
|
|
|
///
|
|
|
|
/// Note that since this treats the coordinate as a homogeneous coordinate, the `w` is ignored.
|
|
|
|
// TODO(pcwalton): Optimize with SIMD.
|
|
|
|
#[inline]
|
|
|
|
pub fn is_zero(self) -> bool {
|
|
|
|
self.x() == 0.0 && self.y() == 0.0 && self.z() == 0.0
|
|
|
|
}
|
2019-01-31 18:29:13 -05:00
|
|
|
|
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
pub fn lerp(self, other: Vector4F, t: f32) -> Vector4F {
|
|
|
|
Vector4F(self.0 + (other.0 - self.0) * F32x4::splat(t))
|
2019-01-31 18:29:13 -05:00
|
|
|
}
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Add<Vector4F> for Vector4F {
|
|
|
|
type Output = Vector4F;
|
2019-01-16 23:41:05 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn add(self, other: Vector4F) -> Vector4F {
|
|
|
|
Vector4F(self.0 + other.0)
|
2019-01-16 23:41:05 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl AddAssign for Vector4F {
|
2019-01-16 23:41:05 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn add_assign(&mut self, other: Vector4F) {
|
2019-01-16 23:41:05 -05:00
|
|
|
self.0 += other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Mul<Vector4F> for Vector4F {
|
|
|
|
type Output = Vector4F;
|
2019-01-15 22:15:33 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn mul(self, other: Vector4F) -> Vector4F {
|
|
|
|
Vector4F(self.0 * other.0)
|
2019-01-15 22:15:33 -05:00
|
|
|
}
|
|
|
|
}
|
2019-02-14 21:53:02 -05:00
|
|
|
|
2019-07-11 18:57:45 -04:00
|
|
|
impl Neg for Vector4F {
|
|
|
|
type Output = Vector4F;
|
|
|
|
/// NB: This does not negate w, because that is rarely what you what for homogeneous
|
|
|
|
/// coordinates.
|
|
|
|
#[inline]
|
|
|
|
fn neg(self) -> Vector4F {
|
|
|
|
Vector4F(self.0 * F32x4::new(-1.0, -1.0, -1.0, 1.0))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 14:51:47 -05:00
|
|
|
impl Sub<Vector4F> for Vector4F {
|
|
|
|
type Output = Vector4F;
|
|
|
|
#[inline]
|
|
|
|
fn sub(self, other: Vector4F) -> Vector4F {
|
|
|
|
Vector4F(self.0 - other.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:39:29 -04:00
|
|
|
impl Default for Vector4F {
|
2019-02-14 21:53:02 -05:00
|
|
|
#[inline]
|
2019-06-03 15:39:29 -04:00
|
|
|
fn default() -> Vector4F {
|
2019-02-14 21:53:02 -05:00
|
|
|
let mut point = F32x4::default();
|
|
|
|
point.set_w(1.0);
|
2019-06-03 15:39:29 -04:00
|
|
|
Vector4F(point)
|
2019-02-14 21:53:02 -05:00
|
|
|
}
|
|
|
|
}
|