forked from M-Labs/nalgebra
Merge pull request #874 from dimforge/more_conversions
More conversions
This commit is contained in:
commit
fb2147673b
10
CHANGELOG.md
10
CHANGELOG.md
@ -4,6 +4,16 @@ documented here.
|
||||
|
||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [0.26.2]
|
||||
###Added
|
||||
- Conversion from an array `[T; D]` to an isometry `Isometry<T, _, D>` (as a translation).
|
||||
- Conversion from a static vector `SVector<T; D>` to an isometry `Isometry<T, _, D>` (as a translation).
|
||||
- Conversion from a point `Point<T; D>` to an isometry `Isometry<T, _, D>` (as a translation).
|
||||
- Conversion of an array `[T; D]` from/to a translation `Translation<T, D>`.
|
||||
- Conversion of a point `Point<T, D>` to a translation `Translation<T, D>`.
|
||||
- Conversion of the tuple of glam types `(Vec3, Quat)` from/to an `Isometry2` or `Isometry3`.
|
||||
- Conversion of a glam type `Vec2/3/4` from/to a `Translation2/3/4`.
|
||||
|
||||
## [0.26.1]
|
||||
Fix a regression introduced in 0.26.0 preventing `DVector` from being serialized with `serde`.
|
||||
|
||||
|
@ -3,7 +3,6 @@ use alloc::vec::Vec;
|
||||
use simba::scalar::{SubsetOf, SupersetOf};
|
||||
use std::convert::{AsMut, AsRef, From, Into};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use simba::simd::{PrimitiveSimdValue, SimdValue};
|
||||
|
||||
@ -24,6 +23,7 @@ use crate::base::{
|
||||
use crate::base::{DVector, VecStorage};
|
||||
use crate::base::{SliceStorage, SliceStorageMut};
|
||||
use crate::constraint::DimEq;
|
||||
use crate::{SMatrix, SVector};
|
||||
|
||||
// TODO: too bad this won't work allo slice conversions.
|
||||
impl<T1, T2, R1, C1, R2, C2> SubsetOf<OMatrix<T2, R2, C2>> for OMatrix<T1, R1, C1>
|
||||
@ -103,35 +103,23 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> IntoIterator
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> {
|
||||
#[inline]
|
||||
fn from(arr: [T; D]) -> Self {
|
||||
unsafe { Self::from_data_statically_unchecked(ArrayStorage([arr; 1])) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> Into<[T; D]> for SVector<T, D> {
|
||||
#[inline]
|
||||
fn into(self) -> [T; D] {
|
||||
// TODO: unfortunately, we must clone because we can move out of an array.
|
||||
self.data.0[0].clone()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_into_asref_1D(
|
||||
($(($NRows: ident, $NCols: ident) => $SZ: expr);* $(;)*) => {$(
|
||||
impl<T> From<[T; $SZ]> for OMatrix<T, $NRows, $NCols>
|
||||
where T: Scalar,
|
||||
DefaultAllocator: Allocator<T, $NRows, $NCols> {
|
||||
#[inline]
|
||||
fn from(arr: [T; $SZ]) -> Self {
|
||||
unsafe {
|
||||
let mut res = Self::new_uninitialized();
|
||||
ptr::copy_nonoverlapping(&arr[0], (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
|
||||
|
||||
res.assume_init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> Into<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
|
||||
where T: Scalar,
|
||||
S: ContiguousStorage<T, $NRows, $NCols> {
|
||||
#[inline]
|
||||
fn into(self) -> [T; $SZ] {
|
||||
let mut res = mem::MaybeUninit::<[T; $SZ]>::uninit();
|
||||
|
||||
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut T, $SZ) };
|
||||
|
||||
unsafe { res.assume_init() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> AsRef<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
|
||||
where T: Scalar,
|
||||
S: ContiguousStorage<T, $NRows, $NCols> {
|
||||
@ -171,33 +159,22 @@ impl_from_into_asref_1D!(
|
||||
(U13, U1) => 13; (U14, U1) => 14; (U15, U1) => 15; (U16, U1) => 16;
|
||||
);
|
||||
|
||||
impl<T: Scalar, const R: usize, const C: usize> From<[[T; R]; C]> for SMatrix<T, R, C> {
|
||||
#[inline]
|
||||
fn from(arr: [[T; R]; C]) -> Self {
|
||||
unsafe { Self::from_data_statically_unchecked(ArrayStorage(arr)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const R: usize, const C: usize> Into<[[T; R]; C]> for SMatrix<T, R, C> {
|
||||
#[inline]
|
||||
fn into(self) -> [[T; R]; C] {
|
||||
self.data.0
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_into_asref_2D(
|
||||
($(($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr));* $(;)*) => {$(
|
||||
impl<T: Scalar> From<[[T; $SZRows]; $SZCols]> for OMatrix<T, $NRows, $NCols>
|
||||
where DefaultAllocator: Allocator<T, $NRows, $NCols> {
|
||||
#[inline]
|
||||
fn from(arr: [[T; $SZRows]; $SZCols]) -> Self {
|
||||
unsafe {
|
||||
let mut res = Self::new_uninitialized();
|
||||
ptr::copy_nonoverlapping(&arr[0][0], (*res.as_mut_ptr()).data.ptr_mut(), $SZRows * $SZCols);
|
||||
|
||||
res.assume_init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, S> Into<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
|
||||
where S: ContiguousStorage<T, $NRows, $NCols> {
|
||||
#[inline]
|
||||
fn into(self) -> [[T; $SZRows]; $SZCols] {
|
||||
let mut res = mem::MaybeUninit::<[[T; $SZRows]; $SZCols]>::uninit();
|
||||
|
||||
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut T, $SZRows * $SZCols) };
|
||||
|
||||
unsafe { res.assume_init() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, S> AsRef<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
|
||||
where S: ContiguousStorage<T, $NRows, $NCols> {
|
||||
#[inline]
|
||||
|
@ -9,6 +9,7 @@ use crate::geometry::{
|
||||
AbstractRotation, Isometry, Isometry3, Similarity, SuperTCategoryOf, TAffine, Transform,
|
||||
Translation, UnitDualQuaternion, UnitQuaternion,
|
||||
};
|
||||
use crate::{Point, SVector};
|
||||
|
||||
/*
|
||||
* This file provides the following conversions:
|
||||
@ -198,6 +199,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField, R, const D: usize> From<[T; D]> for Isometry<T, R, D>
|
||||
where
|
||||
R: AbstractRotation<T, D>,
|
||||
{
|
||||
#[inline]
|
||||
fn from(coords: [T; D]) -> Self {
|
||||
Self::from_parts(coords.into(), R::identity())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField, R, const D: usize> From<SVector<T, D>> for Isometry<T, R, D>
|
||||
where
|
||||
R: AbstractRotation<T, D>,
|
||||
{
|
||||
#[inline]
|
||||
fn from(coords: SVector<T, D>) -> Self {
|
||||
Self::from_parts(coords.into(), R::identity())
|
||||
}
|
||||
}
|
||||
impl<T: SimdRealField, R, const D: usize> From<Point<T, D>> for Isometry<T, R, D>
|
||||
where
|
||||
R: AbstractRotation<T, D>,
|
||||
{
|
||||
#[inline]
|
||||
fn from(coords: Point<T, D>) -> Self {
|
||||
Self::from_parts(coords.into(), R::identity())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + PrimitiveSimdValue, R, const D: usize>
|
||||
From<[Isometry<T::Element, R::Element, D>; 2]> for Isometry<T, R, D>
|
||||
where
|
||||
|
@ -225,17 +225,3 @@ componentwise_constructors_impl!(
|
||||
"# use nalgebra::Point6;\nlet p = Point6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(p.x == 1.0 && p.y == 2.0 && p.z == 3.0 && p.w == 4.0 && p.a == 5.0 && p.b == 6.0);";
|
||||
Point6, Vector6, x:0, y:1, z:2, w:3, a:4, b:5;
|
||||
);
|
||||
|
||||
macro_rules! from_array_impl(
|
||||
($($Point: ident, $len: expr);*) => {$(
|
||||
impl <T: Scalar> From<[T; $len]> for $Point<T> {
|
||||
fn from(coords: [T; $len]) -> Self {
|
||||
Self {
|
||||
coords: coords.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
)*}
|
||||
);
|
||||
|
||||
from_array_impl!(Point1, 1; Point2, 2; Point3, 3; Point4, 4; Point5, 5; Point6, 6);
|
||||
|
@ -81,6 +81,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<[T; D]> for Point<T, D> {
|
||||
#[inline]
|
||||
fn from(coords: [T; D]) -> Self {
|
||||
Point {
|
||||
coords: coords.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> Into<[T; D]> for Point<T, D> {
|
||||
#[inline]
|
||||
fn into(self) -> [T; D] {
|
||||
self.coords.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Point<T, D> {
|
||||
#[inline]
|
||||
fn from(coords: OVector<T, Const<D>>) -> Self {
|
||||
|
@ -11,6 +11,7 @@ use crate::geometry::{
|
||||
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
|
||||
Translation3, UnitDualQuaternion, UnitQuaternion,
|
||||
};
|
||||
use crate::Point;
|
||||
|
||||
/*
|
||||
* This file provides the following conversions:
|
||||
@ -199,6 +200,31 @@ impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Translation<T, D>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<[T; D]> for Translation<T, D> {
|
||||
#[inline]
|
||||
fn from(coords: [T; D]) -> Self {
|
||||
Translation {
|
||||
vector: coords.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<Point<T, D>> for Translation<T, D> {
|
||||
#[inline]
|
||||
fn from(pt: Point<T, D>) -> Self {
|
||||
Translation {
|
||||
vector: pt.coords.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> Into<[T; D]> for Translation<T, D> {
|
||||
#[inline]
|
||||
fn into(self) -> [T; D] {
|
||||
self.vector.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<T::Element, D>; 2]>
|
||||
for Translation<T, D>
|
||||
where
|
||||
|
68
src/third_party/glam/glam_isometry.rs
vendored
68
src/third_party/glam/glam_isometry.rs
vendored
@ -1,5 +1,5 @@
|
||||
use crate::{Isometry2, Isometry3};
|
||||
use glam::{DMat3, DMat4, Mat3, Mat4};
|
||||
use glam::{DMat3, DMat4, DQuat, DVec3, Mat3, Mat4, Quat, Vec3};
|
||||
|
||||
impl From<Isometry2<f32>> for Mat3 {
|
||||
fn from(iso: Isometry2<f32>) -> Mat3 {
|
||||
@ -23,10 +23,74 @@ impl From<Isometry3<f64>> for DMat4 {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Isometry3<f32>> for (Vec3, Quat) {
|
||||
fn from(iso: Isometry3<f32>) -> (Vec3, Quat) {
|
||||
(iso.translation.into(), iso.rotation.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Isometry3<f64>> for (DVec3, DQuat) {
|
||||
fn from(iso: Isometry3<f64>) -> (DVec3, DQuat) {
|
||||
(iso.translation.into(), iso.rotation.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Isometry2<f32>> for (Vec3, Quat) {
|
||||
fn from(iso: Isometry2<f32>) -> (Vec3, Quat) {
|
||||
let tra = Vec3::new(iso.translation.x, iso.translation.y, 0.0);
|
||||
let rot = Quat::from_axis_angle(Vec3::new(0.0, 0.0, 1.0), iso.rotation.angle());
|
||||
(tra, rot)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Isometry2<f64>> for (DVec3, DQuat) {
|
||||
fn from(iso: Isometry2<f64>) -> (DVec3, DQuat) {
|
||||
let tra = DVec3::new(iso.translation.x, iso.translation.y, 0.0);
|
||||
let rot = DQuat::from_axis_angle(DVec3::new(0.0, 0.0, 1.0), iso.rotation.angle());
|
||||
(tra, rot)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "convert-glam-unchecked")]
|
||||
mod unchecked {
|
||||
use crate::{Isometry2, Isometry3, Matrix3, Matrix4};
|
||||
use glam::{DMat3, DMat4, Mat3, Mat4};
|
||||
use glam::{DMat3, DMat4, DQuat, DVec2, DVec3, Mat3, Mat4, Quat, Vec2, Vec3};
|
||||
|
||||
impl From<(Vec3, Quat)> for Isometry3<f32> {
|
||||
fn from((tra, rot): (Vec3, Quat)) -> Self {
|
||||
Isometry3::from_parts(tra.into(), rot.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(DVec3, DQuat)> for Isometry3<f64> {
|
||||
fn from((tra, rot): (DVec3, DQuat)) -> Self {
|
||||
Isometry3::from_parts(tra.into(), rot.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Vec3, Quat)> for Isometry2<f32> {
|
||||
fn from((tra, rot): (Vec3, Quat)) -> Self {
|
||||
Isometry2::new([tra.x, tra.y].into(), rot.to_axis_angle().1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(DVec3, DQuat)> for Isometry2<f64> {
|
||||
fn from((tra, rot): (DVec3, DQuat)) -> Self {
|
||||
Isometry2::new([tra.x, tra.y].into(), rot.to_axis_angle().1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Vec2, Quat)> for Isometry2<f32> {
|
||||
fn from((tra, rot): (Vec2, Quat)) -> Self {
|
||||
Isometry2::new([tra.x, tra.y].into(), rot.to_axis_angle().1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(DVec2, DQuat)> for Isometry2<f64> {
|
||||
fn from((tra, rot): (DVec2, DQuat)) -> Self {
|
||||
Isometry2::new([tra.x, tra.y].into(), rot.to_axis_angle().1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Mat3> for Isometry2<f32> {
|
||||
fn from(mat3: Mat3) -> Isometry2<f32> {
|
||||
|
65
src/third_party/glam/glam_translation.rs
vendored
Normal file
65
src/third_party/glam/glam_translation.rs
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
use crate::{Translation2, Translation3, Translation4};
|
||||
use glam::{DVec2, DVec3, DVec4, Vec2, Vec3, Vec3A, Vec4};
|
||||
|
||||
macro_rules! impl_translation_conversion(
|
||||
($N: ty, $Vec2: ty, $Vec3: ty, $Vec4: ty) => {
|
||||
impl From<$Vec2> for Translation2<$N> {
|
||||
#[inline]
|
||||
fn from(e: $Vec2) -> Translation2<$N> {
|
||||
(*e.as_ref()).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Translation2<$N>> for $Vec2 {
|
||||
#[inline]
|
||||
fn from(e: Translation2<$N>) -> $Vec2 {
|
||||
e.vector.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$Vec3> for Translation3<$N> {
|
||||
#[inline]
|
||||
fn from(e: $Vec3) -> Translation3<$N> {
|
||||
(*e.as_ref()).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Translation3<$N>> for $Vec3 {
|
||||
#[inline]
|
||||
fn from(e: Translation3<$N>) -> $Vec3 {
|
||||
e.vector.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$Vec4> for Translation4<$N> {
|
||||
#[inline]
|
||||
fn from(e: $Vec4) -> Translation4<$N> {
|
||||
(*e.as_ref()).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Translation4<$N>> for $Vec4 {
|
||||
#[inline]
|
||||
fn from(e: Translation4<$N>) -> $Vec4 {
|
||||
e.vector.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl_translation_conversion!(f32, Vec2, Vec3, Vec4);
|
||||
impl_translation_conversion!(f64, DVec2, DVec3, DVec4);
|
||||
|
||||
impl From<Vec3A> for Translation3<f32> {
|
||||
#[inline]
|
||||
fn from(e: Vec3A) -> Translation3<f32> {
|
||||
(*e.as_ref()).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Translation3<f32>> for Vec3A {
|
||||
#[inline]
|
||||
fn from(e: Translation3<f32>) -> Vec3A {
|
||||
e.vector.into()
|
||||
}
|
||||
}
|
1
src/third_party/glam/mod.rs
vendored
1
src/third_party/glam/mod.rs
vendored
@ -4,4 +4,5 @@ mod glam_point;
|
||||
mod glam_quaternion;
|
||||
mod glam_rotation;
|
||||
mod glam_similarity;
|
||||
mod glam_translation;
|
||||
mod glam_unit_complex;
|
||||
|
Loading…
Reference in New Issue
Block a user