diff --git a/.travis.yml b/.travis.yml
index 2b1fd312..e19edab4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,5 +3,7 @@ language: rust
script:
- rustc --version
- cargo --version
+ - cargo build --verbose
- cargo build --verbose --features arbitrary
- - cargo test --verbose --features arbitrary
+ - cargo build --verbose --features serde-serialize
+ - cargo test --verbose --features arbitrary serde-serialize
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c5db34ad..2644b8be 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@ overview of all the added/modified features.
This version is a major rewrite of the library. Major changes are:
* Algebraic traits are now defined by the [alga](https://crates.io/crates/alga) crate.
+ All other mathematical traits, except `Axpy` have been removed from
+ **nalgebra**.
* Methods are now preferred to free functions because they do not require any
trait to be used any more.
* Most algebraic entities can be parametrized by type-level integers
@@ -19,7 +21,8 @@ This version is a major rewrite of the library. Major changes are:
* More transformation types have been added: unit-sized complex numbers (for
2D rotations), affine/projective/general transformations with `Affine2/3`,
`Projective2/3`, and `Transform2/3`.
- * Serde serialization is now supported instead of `rustc_serialize`.
+ * Serde serialization is now supported instead of `rustc_serialize`. Enable
+ it with the `serde-serialize` feature.
* Matrix **slices** are now implemented.
### Added
diff --git a/Cargo.toml b/Cargo.toml
index 398f0db9..d109fe3a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,7 @@ path = "src/lib.rs"
[features]
arbitrary = [ "quickcheck" ]
+serde-serialize = [ "serde", "serde_derive" ]
[dependencies]
typenum = "1.4"
@@ -25,9 +26,9 @@ rand = "0.3"
num-traits = "0.1"
num-complex = "0.1"
approx = "0.1"
-alga = "0.4"
-serde = "0.9"
-serde_derive = "0.9"
+alga = "0.5"
+serde = { version = "0.9", optional = true }
+serde_derive = { version = "0.9", optional = true }
# clippy = "*"
[dependencies.quickcheck]
diff --git a/Makefile b/Makefile
index c2b68b5c..ab97c6f9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
all:
- CARGO_INCREMENTAL=1 cargo build --features "arbitrary"
+ CARGO_INCREMENTAL=1 cargo build --features "arbitrary serde-serialize"
doc:
- CARGO_INCREMENTAL=1 cargo doc --no-deps
+ CARGO_INCREMENTAL=1 cargo doc --no-deps --features "arbitrary serde-serialize"
bench:
cargo bench
test:
- CARGO_INCREMENTAL=1 cargo test --features "arbitrary"
+ CARGO_INCREMENTAL=1 cargo test --features "arbitrary serde-serialize"
diff --git a/README.md b/README.md
index 1cb98bef..c7eeeabb 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
- Users guide | Documentation | Forum
+ Users guide | Documentation | Forum
diff --git a/src/core/coordinates.rs b/src/core/coordinates.rs
index 3a8f371f..63d81166 100644
--- a/src/core/coordinates.rs
+++ b/src/core/coordinates.rs
@@ -23,7 +23,8 @@ macro_rules! coords_impl(
/// Data structure used to provide access to matrix and vector coordinates with the dot
/// notation, e.g., `v.x` is the same as `v[0]` for a vector.
#[repr(C)]
- #[derive(Eq, PartialEq, Clone, Hash, Debug, Copy, Serialize, Deserialize)]
+ #[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
+ #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct $T {
$(pub $comps: N),*
}
diff --git a/src/core/dimension.rs b/src/core/dimension.rs
index 20819b68..d3bd819d 100644
--- a/src/core/dimension.rs
+++ b/src/core/dimension.rs
@@ -8,7 +8,8 @@ use std::ops::{Add, Sub, Mul, Div};
use typenum::{self, Unsigned, UInt, B1, Bit, UTerm, Sum, Prod, Diff, Quot};
/// Dim of dynamically-sized algebraic entities.
-#[derive(Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize)]
+#[derive(Clone, Copy, Eq, PartialEq, Debug)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Dynamic {
value: usize
}
@@ -161,7 +162,8 @@ pub trait NamedDim: Sized + Any + Unsigned {
type Name: DimName;
}
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct U1;
impl Dim for U1 {
@@ -197,7 +199,8 @@ impl NamedDim for typenum::U1{
macro_rules! named_dimension(
($($D: ident),* $(,)*) => {$(
- #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+ #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+ #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct $D;
impl Dim for $D {
diff --git a/src/core/matrix.rs b/src/core/matrix.rs
index c92b76a8..004888e8 100644
--- a/src/core/matrix.rs
+++ b/src/core/matrix.rs
@@ -79,13 +79,14 @@ Matrix>::Alloc as Allocator>:
/// dynamically-sized column vector should be represented as a `Matrix` (given
/// some concrete types for `N` and a compatible data storage type `S`).
#[repr(C)]
-#[derive(Serialize, Deserialize, Hash, Debug, Clone, Copy)]
+#[derive(Hash, Debug, Clone, Copy)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Matrix {
/// The data storage that contains all the matrix components and informations about its number
/// of rows and column (if needed).
pub data: S,
- #[serde(skip_serializing, skip_deserializing)]
+ #[cfg_attr(feature = "serde-serialize", serde(skip_serializing, skip_deserializing))]
_phantoms: PhantomData<(N, R, C)>
}
diff --git a/src/core/matrix_array.rs b/src/core/matrix_array.rs
index 5ef36198..ebc20e00 100644
--- a/src/core/matrix_array.rs
+++ b/src/core/matrix_array.rs
@@ -1,11 +1,17 @@
-use std::mem;
-use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Mul};
use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
+
+#[cfg(feature = "serde-serialize")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};
+#[cfg(feature = "serde-serialize")]
use serde::ser::SerializeSeq;
+#[cfg(feature = "serde-serialize")]
use serde::de::{SeqVisitor, Visitor};
+#[cfg(feature = "serde-serialize")]
+use std::mem;
+#[cfg(feature = "serde-serialize")]
+use std::marker::PhantomData;
use typenum::Prod;
use generic_array::{ArrayLength, GenericArray};
@@ -199,6 +205,7 @@ unsafe impl OwnedStorage for MatrixArray
*
*/
// XXX: open an issue for GenericArray so that it implements serde traits?
+#[cfg(feature = "serde-serialize")]
impl Serialize for MatrixArray
where N: Scalar + Serialize,
R: DimName,
@@ -220,6 +227,7 @@ where N: Scalar + Serialize,
}
+#[cfg(feature = "serde-serialize")]
impl Deserialize for MatrixArray
where N: Scalar + Deserialize,
R: DimName,
@@ -237,11 +245,13 @@ where N: Scalar + Deserialize,
}
+#[cfg(feature = "serde-serialize")]
/// A visitor that produces a matrix array.
struct MatrixArrayVisitor {
marker: PhantomData<(N, R, C)>
}
+#[cfg(feature = "serde-serialize")]
impl MatrixArrayVisitor
where N: Scalar,
R: DimName,
@@ -257,6 +267,7 @@ where N: Scalar,
}
}
+#[cfg(feature = "serde-serialize")]
impl Visitor for MatrixArrayVisitor
where N: Scalar + Deserialize,
R: DimName,
diff --git a/src/core/matrix_vec.rs b/src/core/matrix_vec.rs
index b492ec47..51a02640 100644
--- a/src/core/matrix_vec.rs
+++ b/src/core/matrix_vec.rs
@@ -12,7 +12,8 @@ use core::default_allocator::DefaultAllocator;
*/
/// A Vec-based matrix data storage. It may be dynamically-sized.
#[repr(C)]
-#[derive(Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[derive(Eq, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct MatrixVec {
data: Vec,
nrows: R,
diff --git a/src/core/mod.rs b/src/core/mod.rs
index f37ec9b8..356dd29d 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -1,4 +1,4 @@
-//! Data structures for vector and matrix computations.
+//! [Reexported at the root of this crate.] Data structures for vector and matrix computations.
pub mod dimension;
pub mod constraint;
diff --git a/src/core/unit.rs b/src/core/unit.rs
index c8e8c578..cc7ea1df 100644
--- a/src/core/unit.rs
+++ b/src/core/unit.rs
@@ -10,7 +10,8 @@ use alga::linear::NormedSpace;
///
/// Use `.as_ref()` or `.unwrap()` to obtain the undelying value by-reference or by-move.
#[repr(C)]
-#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy, Serialize, Deserialize)]
+#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Unit {
value: T
}
diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs
index 5be41990..67d2e7e8 100644
--- a/src/geometry/isometry.rs
+++ b/src/geometry/isometry.rs
@@ -18,7 +18,8 @@ pub type OwnedIsometryBase =
/// A direct isometry, i.e., a rotation followed by a translation.
#[repr(C)]
-#[derive(Hash, Debug, Clone, Copy, Serialize, Deserialize)]
+#[derive(Hash, Debug, Clone, Copy)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct IsometryBase {
/// The pure rotational part of this isometry.
pub rotation: R,
@@ -27,7 +28,7 @@ pub struct IsometryBase {
// One dummy private field just to prevent explicit construction.
- #[serde(skip_serializing, skip_deserializing)]
+ #[cfg_attr(feature = "serde-serialize", serde(skip_serializing, skip_deserializing))]
_noconstruct: PhantomData
}
diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs
index 0ee4c9e0..d99e82cb 100644
--- a/src/geometry/mod.rs
+++ b/src/geometry/mod.rs
@@ -1,4 +1,5 @@
-//! Data structures for points and usual transformations (rotations, isometries, etc.)
+//! [Reexported at the root of this crate.] Data structures for points and usual transformations
+//! (rotations, isometries, etc.)
mod op_macros;
diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs
index 900fd74a..3936ccef 100644
--- a/src/geometry/orthographic.rs
+++ b/src/geometry/orthographic.rs
@@ -13,7 +13,8 @@ use core::helper;
use geometry::{PointBase, OwnedPoint};
/// A 3D orthographic projection stored as an homogeneous 4x4 matrix.
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)] // FIXME: Hash
+#[derive(Debug, Clone, Copy)] // FIXME: Hash
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct OrthographicBase> {
matrix: SquareMatrix
}
diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs
index c9110ea9..9c518546 100644
--- a/src/geometry/perspective.rs
+++ b/src/geometry/perspective.rs
@@ -13,7 +13,8 @@ use core::helper;
use geometry::{PointBase, OwnedPoint};
/// A 3D perspective projection stored as an homogeneous 4x4 matrix.
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)] // FIXME: Hash
+#[derive(Debug, Clone, Copy)] // FIXME: Hash
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct PerspectiveBase> {
matrix: SquareMatrix
}
diff --git a/src/geometry/point.rs b/src/geometry/point.rs
index 70cba65f..370fc3db 100644
--- a/src/geometry/point.rs
+++ b/src/geometry/point.rs
@@ -23,7 +23,8 @@ pub type OwnedPoint = PointBase>::Buffe
/// A point in a n-dimensional euclidean space.
#[repr(C)]
-#[derive(Hash, Debug, Serialize, Deserialize)]
+#[derive(Hash, Debug)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct PointBase> {
/// The coordinates of this point, i.e., the shift from the origin.
pub coords: ColumnVector
diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs
index e970ae15..784dc20a 100644
--- a/src/geometry/quaternion.rs
+++ b/src/geometry/quaternion.rs
@@ -21,7 +21,8 @@ pub type OwnedUnitQuaternionBase = UnitQuaternionBase` for a quaternion
/// that may be used as a rotation.
#[repr(C)]
-#[derive(Hash, Debug, Copy, Clone, Serialize, Deserialize)]
+#[derive(Hash, Debug, Copy, Clone)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct QuaternionBase> {
/// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order.
pub coords: ColumnVector
@@ -275,6 +276,121 @@ impl fmt::Display for QuaternionBase
}
/// A unit quaternions. May be used to represent a rotation.
+///
+///
+///
+///
+/// Due to a [bug](https://github.com/rust-lang/rust/issues/32077) in rustdoc, the documentation
+/// below has been written manually lists only method signatures.
+/// Trait implementations are not listed either.
+///
+///
+///
+/// Please refer directly to the documentation written above each function definition on the source
+/// code for more details.
+///
+/// Methods
+///
+///
+///
+/// fn angle(&self) -> N
+///
+///
+/// fn angle_to(&self, other: &UnitQuaternionBase) -> N
+///
+///
+/// fn axis(&self) -> Option<Unit<OwnedColumnVector>>
+///
+///
+/// fn clone_owned(&self) -> OwnedUnitQuaternionBase
+///
+///
+///
+/// fn conjugate(&self) -> OwnedUnitQuaternionBase
+///
+///
+/// fn exp(&self) -> OwnedQuaternionBase
+///
+///
+/// fn from_axis_angle(axis: &Unit<ColumnVector>, angle: N) -> Self
+///
+///
+/// fn from_euler_angles(roll: N, pitch: N, yaw: N) -> Self
+///
+///
+/// fn from_quaternion(q: QuaternionBase) -> Self
+///
+///
+/// fn from_rotation_matrix(rotmat: &RotationBase) -> Self
+///
+///
+/// fn from_scaled_axis(axisangle: ColumnVector) -> Self
+///
+///
+/// fn identity() -> Self
+///
+///
+/// fn into_owned(self) -> OwnedUnitQuaternionBase
+///
+///
+/// fn inverse_mut(&mut self)
+///
+///
+/// fn inverse(&self) -> OwnedUnitQuaternionBase
+///
+///
+/// fn lerp(&self, other: &UnitQuaternionBase, t: N) -> OwnedQuaternionBase
+///
+///
+/// fn ln(&self) -> OwnedQuaternionBase
+///
+///
+/// fn look_at_lh(dir: &ColumnVector, up: &ColumnVector) -> Self
+///
+///
+/// fn look_at_rh(dir: &ColumnVector, up: &ColumnVector) -> Self
+///
+///
+/// fn new(axisangle: ColumnVector) -> Self
+///
+///
+/// fn new_observer_frame(dir: &ColumnVector, up: &ColumnVector) -> Self
+///
+///
+/// fn nlerp(&self, other: &UnitQuaternionBase, t: N) -> OwnedUnitQuaternionBase
+///
+///
+/// fn powf(&self, n: N) -> OwnedUnitQuaternionBase
+///
+///
+/// fn quaternion(&self) -> &QuaternionBase
+///
+///
+/// fn rotation_between(a: &ColumnVector, b: &ColumnVector) -> Option<Self>
+///
+///
+/// fn rotation_to(&self, other: &UnitQuaternionBase) -> OwnedUnitQuaternionBase
+///
+///
+/// fn scaled_axis(&self) -> OwnedColumnVector
+///
+///
+/// fn scaled_rotation_between(a: &ColumnVector, b: &ColumnVector, s: N) -> Option<Self>
+///
+///
+/// fn slerp(&self, other: &UnitQuaternionBase, t: N) -> OwnedUnitQuaternionBase
+///
+///
+/// fn to_homogeneous(&self) -> OwnedSquareMatrix
+///
+///
+/// fn to_rotation_matrix(&self) -> OwnedRotation
+///
+///
+/// fn try_slerp(&self, other: &UnitQuaternionBase, t: N, epsilon: N) -> Option<OwnedUnitQuaternionBase>
+///
pub type UnitQuaternionBase = Unit>;
diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs
index d447d585..a1063cbb 100644
--- a/src/geometry/rotation.rs
+++ b/src/geometry/rotation.rs
@@ -15,7 +15,8 @@ pub type OwnedRotation = RotationBase>::
/// A rotation matrix.
#[repr(C)]
-#[derive(Hash, Debug, Clone, Copy, Serialize, Deserialize)]
+#[derive(Hash, Debug, Clone, Copy)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct RotationBase {
matrix: SquareMatrix
}
diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs
index 2a072bd6..43e4ec1f 100644
--- a/src/geometry/similarity.rs
+++ b/src/geometry/similarity.rs
@@ -17,7 +17,8 @@ pub type OwnedSimilarityBase =
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
#[repr(C)]
-#[derive(Hash, Debug, Clone, Copy, Serialize, Deserialize)]
+#[derive(Hash, Debug, Clone, Copy)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct SimilarityBase {
/// The part of this similarity that does not include the scaling factor.
pub isometry: IsometryBase,
diff --git a/src/geometry/transform.rs b/src/geometry/transform.rs
index 726e0342..23563d80 100644
--- a/src/geometry/transform.rs
+++ b/src/geometry/transform.rs
@@ -52,15 +52,18 @@ where T1: TCategory,
}
/// Tag representing the most general (not necessarily inversible) `Transform` type.
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum TGeneral { }
/// Tag representing the most general inversible `Transform` type.
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum TProjective { }
/// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`.
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum TAffine { }
impl TCategory for TGeneral {
@@ -155,11 +158,12 @@ pub type OwnedTransform
/// It is stored as a matrix with dimensions `(D + 1, D + 1)`, e.g., it stores a 4x4 matrix for a
/// 3D transformation.
#[repr(C)]
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)] // FIXME: Hash
+#[derive(Debug, Clone, Copy)] // FIXME: Hash
+#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct TransformBase, S, C: TCategory> {
matrix: SquareMatrix, S>,
- #[serde(skip_serializing, skip_deserializing)]
+ #[cfg_attr(feature = "serde-serialize", serde(skip_serializing, skip_deserializing))]
_phantom: PhantomData
}
diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs
index 2fb28671..ac7b1fd8 100644
--- a/src/geometry/translation.rs
+++ b/src/geometry/translation.rs
@@ -14,7 +14,8 @@ pub type OwnedTranslation = TranslationBase*/> {
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
/// translated.
diff --git a/src/geometry/unit_complex.rs b/src/geometry/unit_complex.rs
index 0d4eb876..8d371234 100644
--- a/src/geometry/unit_complex.rs
+++ b/src/geometry/unit_complex.rs
@@ -8,6 +8,100 @@ use core::dimension::U2;
use geometry::Rotation2;
/// A complex number with a norm equal to 1.
+///
+///
+///
+/// Due to a [bug](https://github.com/rust-lang/rust/issues/32077) in rustdoc, the documentation
+/// below has been written manually lists only method signatures.
+/// Trait implementations are not listed either.
+///
+///
+///
+/// Please refer directly to the documentation written above each function definition on the source
+/// code for more details.
+///
+///
+/// Methods
+///
+///
+/// fn angle(&self) -> N
+///
+///
+///
+/// fn angle_to(&self, other: &Self) -> N
+///
+///
+///
+/// fn complex(&self) -> &Complex
+///
+///
+///
+/// fn conjugate(&self) -> Self
+///
+///
+///
+///
+///
+/// fn from_angle(angle: N) -> Self
+///
+///
+///
+/// fn from_complex(q: Complex) -> Self
+///
+///
+///
+/// fn from_rotation_matrix(rotmat: &RotationBase) -> Self
+///
+///
+///
+/// fn from_scaled_axis(axisangle: ColumnVector) -> Self
+///
+///
+///
+/// fn identity() -> Self
+///
+///
+///
+/// fn inverse(&self) -> Self
+///
+///
+///
+/// fn inverse_mut(&mut self)
+///
+///
+///
+/// fn new(angle: N) -> Self
+///
+///
+///
+/// fn powf(&self, n: N) -> Self
+///
+///
+///
+/// fn rotation_between(a: &ColumnVector, b: &ColumnVector) -> Self
+///
+///
+///
+/// fn rotation_to(&self, other: &Self) -> Self
+///
+///
+///
+/// fn scaled_axis(&self) -> Vector1
+///
+///
+///
+/// fn scaled_rotation_between(a: &ColumnVector, b: &ColumnVector, s: N) -> Self
+///
+///
+///
+/// fn to_homogeneous(&self) -> Matrix3
+///
+///
+///
pub type UnitComplex = Unit>;
impl UnitComplex {
diff --git a/src/lib.rs b/src/lib.rs
index f713768d..76a551e5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -67,7 +67,7 @@ an optimized set of tools for computer graphics and physics. Those features incl
`Transform2`, `Transform3`.
* 3D projections for computer graphics: `Perspective3`, `Orthographic3`.
* Linear algebra and data analysis operators: QR decomposition, eigen-decomposition.
-* Implements all meaningful traits from the [alga](https://crates.io/crates/alga) crate for
+* Implements traits from the [alga](https://crates.io/crates/alga) crate for
generic programming.
*/
@@ -89,7 +89,9 @@ an optimized set of tools for computer graphics and physics. Those features incl
#[cfg(feature = "arbitrary")]
extern crate quickcheck;
+#[cfg(feature = "serde")]
extern crate serde;
+#[cfg(feature = "serde")]
#[macro_use]
extern crate serde_derive;
extern crate num_traits as num;