bug #369 - Quaternion alignment is broken

The problem was two-fold:
 * missing aligned operator new
 * Flags were mis-computed, the Aligned constant was misused
This commit is contained in:
Benoit Jacob 2011-10-31 09:23:41 -04:00
parent 0609dbeec6
commit 9df2f5c923
2 changed files with 13 additions and 5 deletions

View File

@ -185,7 +185,7 @@ public:
return typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type( return typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type(
coeffs().template cast<NewScalarType>()); coeffs().template cast<NewScalarType>());
} }
#ifdef EIGEN_QUATERNIONBASE_PLUGIN #ifdef EIGEN_QUATERNIONBASE_PLUGIN
# include EIGEN_QUATERNIONBASE_PLUGIN # include EIGEN_QUATERNIONBASE_PLUGIN
#endif #endif
@ -225,22 +225,25 @@ struct traits<Quaternion<_Scalar,_Options> >
typedef _Scalar Scalar; typedef _Scalar Scalar;
typedef Matrix<_Scalar,4,1,_Options> Coefficients; typedef Matrix<_Scalar,4,1,_Options> Coefficients;
enum{ enum{
IsAligned = bool(EIGEN_ALIGN) && ((int(_Options)&Aligned)==Aligned), IsAligned = internal::traits<Coefficients>::Flags & AlignedBit,
Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit
}; };
}; };
} }
template<typename _Scalar, int _Options> template<typename _Scalar, int _Options>
class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >{ class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >
{
typedef QuaternionBase<Quaternion<_Scalar,_Options> > Base; typedef QuaternionBase<Quaternion<_Scalar,_Options> > Base;
enum { IsAligned = internal::traits<Quaternion>::IsAligned };
public: public:
typedef _Scalar Scalar; typedef _Scalar Scalar;
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion)
using Base::operator*=; using Base::operator*=;
typedef typename internal::traits<Quaternion<Scalar,_Options> >::Coefficients Coefficients; typedef typename internal::traits<Quaternion>::Coefficients Coefficients;
typedef typename Base::AngleAxisType AngleAxisType; typedef typename Base::AngleAxisType AngleAxisType;
/** Default constructor leaving the quaternion uninitialized. */ /** Default constructor leaving the quaternion uninitialized. */
@ -274,6 +277,8 @@ public:
inline Coefficients& coeffs() { return m_coeffs;} inline Coefficients& coeffs() { return m_coeffs;}
inline const Coefficients& coeffs() const { return m_coeffs;} inline const Coefficients& coeffs() const { return m_coeffs;}
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(IsAligned)
protected: protected:
Coefficients m_coeffs; Coefficients m_coeffs;

View File

@ -120,6 +120,10 @@ template<typename Scalar, int Options> void quaternion(void)
VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1); VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);
Quaternion<double> q1d = q1.template cast<double>(); Quaternion<double> q1d = q1.template cast<double>();
VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1); VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
// test bug 369 - improper alignment.
Quaternionx *q = new Quaternionx;
delete q;
} }
template<typename Scalar> void mapQuaternion(void){ template<typename Scalar> void mapQuaternion(void){
@ -191,7 +195,6 @@ template<typename PlainObjectType> void check_const_correctness(const PlainObjec
VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) ); VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
} }
void test_geo_quaternion() void test_geo_quaternion()
{ {
for(int i = 0; i < g_repeat; i++) { for(int i = 0; i < g_repeat; i++) {