1// This file is part of Eigen, a lightweight C++ template library 2// for linear algebra. 3// 4// Copyright (C) 2009 Gael Guennebaud <[email protected]> 5// 6// This Source Code Form is subject to the terms of the Mozilla 7// Public License v. 2.0. If a copy of the MPL was not distributed 8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10#ifndef EIGEN_ALIGNED_VECTOR3 11#define EIGEN_ALIGNED_VECTOR3 12 13#include "../../Eigen/Geometry" 14 15#include "../../Eigen/src/Core/util/DisableStupidWarnings.h" 16 17namespace Eigen { 18 19/** 20 * \defgroup AlignedVector3_Module Aligned vector3 module 21 * 22 * \code 23 * #include <unsupported/Eigen/AlignedVector3> 24 * \endcode 25 */ 26 //@{ 27 28 29/** \class AlignedVector3 30 * 31 * \brief A vectorization friendly 3D vector 32 * 33 * This class represents a 3D vector internally using a 4D vector 34 * such that vectorization can be seamlessly enabled. Of course, 35 * the same result can be achieved by directly using a 4D vector. 36 * This class makes this process simpler. 37 * 38 */ 39// TODO specialize Cwise 40template<typename _Scalar> class AlignedVector3; 41 42namespace internal { 43template<typename _Scalar> struct traits<AlignedVector3<_Scalar> > 44 : traits<Matrix<_Scalar,3,1,0,4,1> > 45{ 46}; 47} 48 49template<typename _Scalar> class AlignedVector3 50 : public MatrixBase<AlignedVector3<_Scalar> > 51{ 52 typedef Matrix<_Scalar,4,1> CoeffType; 53 CoeffType m_coeffs; 54 public: 55 56 typedef MatrixBase<AlignedVector3<_Scalar> > Base; 57 EIGEN_DENSE_PUBLIC_INTERFACE(AlignedVector3) 58 using Base::operator*; 59 60 inline Index rows() const { return 3; } 61 inline Index cols() const { return 1; } 62 63 Scalar* data() { return m_coeffs.data(); } 64 const Scalar* data() const { return m_coeffs.data(); } 65 Index innerStride() const { return 1; } 66 Index outerStride() const { return 3; } 67 68 inline const Scalar& coeff(Index row, Index col) const 69 { return m_coeffs.coeff(row, col); } 70 71 inline Scalar& coeffRef(Index row, Index col) 72 { return m_coeffs.coeffRef(row, col); } 73 74 inline const Scalar& coeff(Index index) const 75 { return m_coeffs.coeff(index); } 76 77 inline Scalar& coeffRef(Index index) 78 { return m_coeffs.coeffRef(index);} 79 80 81 inline AlignedVector3() 82 {} 83 84 inline AlignedVector3(const Scalar& x, const Scalar& y, const Scalar& z) 85 : m_coeffs(x, y, z, Scalar(0)) 86 {} 87 88 inline AlignedVector3(const AlignedVector3& other) 89 : Base(), m_coeffs(other.m_coeffs) 90 {} 91 92 template<typename XprType, int Size=XprType::SizeAtCompileTime> 93 struct generic_assign_selector {}; 94 95 template<typename XprType> struct generic_assign_selector<XprType,4> 96 { 97 inline static void run(AlignedVector3& dest, const XprType& src) 98 { 99 dest.m_coeffs = src; 100 } 101 }; 102 103 template<typename XprType> struct generic_assign_selector<XprType,3> 104 { 105 inline static void run(AlignedVector3& dest, const XprType& src) 106 { 107 dest.m_coeffs.template head<3>() = src; 108 dest.m_coeffs.w() = Scalar(0); 109 } 110 }; 111 112 template<typename Derived> 113 inline AlignedVector3(const MatrixBase<Derived>& other) 114 { 115 generic_assign_selector<Derived>::run(*this,other.derived()); 116 } 117 118 inline AlignedVector3& operator=(const AlignedVector3& other) 119 { m_coeffs = other.m_coeffs; return *this; } 120 121 template <typename Derived> 122 inline AlignedVector3& operator=(const MatrixBase<Derived>& other) 123 { 124 generic_assign_selector<Derived>::run(*this,other.derived()); 125 return *this; 126 } 127 128 inline AlignedVector3 operator+(const AlignedVector3& other) const 129 { return AlignedVector3(m_coeffs + other.m_coeffs); } 130 131 inline AlignedVector3& operator+=(const AlignedVector3& other) 132 { m_coeffs += other.m_coeffs; return *this; } 133 134 inline AlignedVector3 operator-(const AlignedVector3& other) const 135 { return AlignedVector3(m_coeffs - other.m_coeffs); } 136 137 inline AlignedVector3 operator-() const 138 { return AlignedVector3(-m_coeffs); } 139 140 inline AlignedVector3 operator-=(const AlignedVector3& other) 141 { m_coeffs -= other.m_coeffs; return *this; } 142 143 inline AlignedVector3 operator*(const Scalar& s) const 144 { return AlignedVector3(m_coeffs * s); } 145 146 inline friend AlignedVector3 operator*(const Scalar& s,const AlignedVector3& vec) 147 { return AlignedVector3(s * vec.m_coeffs); } 148 149 inline AlignedVector3& operator*=(const Scalar& s) 150 { m_coeffs *= s; return *this; } 151 152 inline AlignedVector3 operator/(const Scalar& s) const 153 { return AlignedVector3(m_coeffs / s); } 154 155 inline AlignedVector3& operator/=(const Scalar& s) 156 { m_coeffs /= s; return *this; } 157 158 inline Scalar dot(const AlignedVector3& other) const 159 { 160 eigen_assert(m_coeffs.w()==Scalar(0)); 161 eigen_assert(other.m_coeffs.w()==Scalar(0)); 162 return m_coeffs.dot(other.m_coeffs); 163 } 164 165 inline void normalize() 166 { 167 m_coeffs /= norm(); 168 } 169 170 inline AlignedVector3 normalized() const 171 { 172 return AlignedVector3(m_coeffs / norm()); 173 } 174 175 inline Scalar sum() const 176 { 177 eigen_assert(m_coeffs.w()==Scalar(0)); 178 return m_coeffs.sum(); 179 } 180 181 inline Scalar squaredNorm() const 182 { 183 eigen_assert(m_coeffs.w()==Scalar(0)); 184 return m_coeffs.squaredNorm(); 185 } 186 187 inline Scalar norm() const 188 { 189 using std::sqrt; 190 return sqrt(squaredNorm()); 191 } 192 193 inline AlignedVector3 cross(const AlignedVector3& other) const 194 { 195 return AlignedVector3(m_coeffs.cross3(other.m_coeffs)); 196 } 197 198 template<typename Derived> 199 inline bool isApprox(const MatrixBase<Derived>& other, const RealScalar& eps=NumTraits<Scalar>::dummy_precision()) const 200 { 201 return m_coeffs.template head<3>().isApprox(other,eps); 202 } 203 204 CoeffType& coeffs() { return m_coeffs; } 205 const CoeffType& coeffs() const { return m_coeffs; } 206}; 207 208namespace internal { 209 210template<typename _Scalar> 211struct eval<AlignedVector3<_Scalar>, Dense> 212{ 213 typedef const AlignedVector3<_Scalar>& type; 214}; 215 216template<typename Scalar> 217struct evaluator<AlignedVector3<Scalar> > 218 : evaluator<Matrix<Scalar,4,1> > 219{ 220 typedef AlignedVector3<Scalar> XprType; 221 typedef evaluator<Matrix<Scalar,4,1> > Base; 222 223 evaluator(const XprType &m) : Base(m.coeffs()) {} 224}; 225 226} 227 228//@} 229 230} 231 232#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h" 233 234#endif // EIGEN_ALIGNED_VECTOR3 235