18 #include <Eigen/Geometry>
27 #define CC_MAT_R11 m_mat[0]
28 #define CC_MAT_R21 m_mat[1]
29 #define CC_MAT_R31 m_mat[2]
30 #define CC_MAT_R41 m_mat[3]
32 #define CC_MAT_R12 m_mat[4]
33 #define CC_MAT_R22 m_mat[5]
34 #define CC_MAT_R32 m_mat[6]
35 #define CC_MAT_R42 m_mat[7]
37 #define CC_MAT_R13 m_mat[8]
38 #define CC_MAT_R23 m_mat[9]
39 #define CC_MAT_R33 m_mat[10]
40 #define CC_MAT_R43 m_mat[11]
42 #define CC_MAT_R14 m_mat[12]
43 #define CC_MAT_R24 m_mat[13]
44 #define CC_MAT_R34 m_mat[14]
45 #define CC_MAT_R44 m_mat[15]
55 const Eigen::Matrix<double, 4, 4>& mat) {
60 const Eigen::Matrix<T, 3, 3>& mat) {
69 Eigen::Matrix4f matrix = Eigen::Matrix<float, 4, 4>(mat.
data());
70 return matrix.cast<T>();
74 Eigen::Matrix4d matrix = Eigen::Matrix<double, 4, 4>(mat.
data());
75 return matrix.cast<T>();
80 Eigen::Matrix<T, 3, 3> m = Eigen::Matrix<T, 3, 3>::Zero();
89 Eigen::Matrix<T, 3, 3> m = Eigen::Matrix<T, 3, 3>::Zero();
98 inline ccGLMatrixTpl(
const Eigen::Matrix<float, 4, 4>& mat) { *
this = mat; }
103 inline ccGLMatrixTpl(
const Eigen::Matrix<float, 3, 3>& mat) { *
this = mat; }
110 const float*
data = mat.data();
116 const double*
data = mat.data();
156 m_mat[i] =
static_cast<T
>(mat16f[i]);
165 m_mat[i] =
static_cast<T
>(mat16d[i]);
233 T f = (c < 0 ? -c : c);
243 x.
x =
static_cast<T
>(1);
245 x.
z =
static_cast<T
>(1);
248 x.
y =
static_cast<T
>(1);
250 x.
z =
static_cast<T
>(1);
258 T c3 = c1 * c2 * u.
dot(v);
261 for (
unsigned i = 0; i < 3; i++) {
262 for (
unsigned j = 0; j < 3; j++) {
263 mat[i * 4 + j] = c3 * v.
u[i] * u.
u[j] -
264 c2 * v.
u[i] * v.
u[j] -
265 c1 * u.
u[i] * u.
u[j];
267 mat[i * 4 + i] +=
static_cast<T
>(1);
282 mat[0] = c + hvx * v.
x;
287 mat[5] = c + h * v.
y * v.
y;
292 mat[10] = c + hvz * v.
z;
307 T* mat = rotMat.
data();
311 Tq q00 = q[0] * q[0];
312 Tq q11 = q[1] * q[1];
313 Tq q22 = q[2] * q[2];
314 Tq q33 = q[3] * q[3];
316 mat[0] =
static_cast<T
>(q00 + q11 - q22 - q33);
317 mat[5] =
static_cast<T
>(q00 - q11 + q22 - q33);
318 mat[10] =
static_cast<T
>(q00 - q11 - q22 + q33);
319 mat[15] =
static_cast<T
>(1);
324 Tq q03 = q[0] * q[3];
325 Tq q13 = q[1] * q[3];
326 Tq q23 = q[2] * q[3];
327 Tq q02 = q[0] * q[2];
328 Tq q12 = q[1] * q[2];
329 Tq q01 = q[0] * q[1];
331 mat[1] =
static_cast<T
>((q12 + q03) * 2);
332 mat[2] =
static_cast<T
>((q13 - q02) * 2);
333 mat[4] =
static_cast<T
>((q12 - q03) * 2);
334 mat[6] =
static_cast<T
>((q23 + q01) * 2);
335 mat[8] =
static_cast<T
>((q13 + q02) * 2);
336 mat[9] =
static_cast<T
>((q23 - q01) * 2);
347 const Eigen::Matrix<T, 4, 1>& qvec) {
348 const Eigen::Matrix<T, 4, 1> normalized_qvec =
350 const Eigen::Quaternion<T> quat(normalized_qvec(0), normalized_qvec(1),
351 normalized_qvec(2), normalized_qvec(3));
352 return quat.toRotationMatrix();
361 Eigen::Matrix<T, 4, 1> t_qvec;
366 const Eigen::Matrix<T, 4, 1> normalized_qvec =
368 const Eigen::Quaternion<T> quat(normalized_qvec(0), normalized_qvec(1),
369 normalized_qvec(2), normalized_qvec(3));
378 const Eigen::Matrix<T, 4, 1>& qvec) {
379 const T norm = qvec.norm();
384 return Eigen::Matrix<T, 4, 1>(
static_cast<T
>(1.0), qvec(1), qvec(2),
396 Eigen::Quaternion<T> t_q = Eigen::Quaternion<T>(
ToEigenMatrix3(*
this));
409 Eigen::AngleAxis<T> v = Eigen::AngleAxis<T>(
ToEigenMatrix3(*
this));
410 alpha_rad = v.angle();
411 axis3D.
x = v.axis().x();
412 axis3D.
y = v.axis().y();
413 axis3D.
z = v.axis().z();
423 Eigen::Matrix<T, 3, 1> euler_angles =
425 rz = euler_angles.z();
426 ry = euler_angles.y();
427 rx = euler_angles.x();
452 T* mat = matrix.
data();
461 mat[2] = -uForward.
x;
462 mat[6] = -uForward.
y;
463 mat[10] = -uForward.
z;
468 mat[15] =
static_cast<T
>(1);
478 QStringList valuesStr =
486 T* matValues = matrix.
data();
488 matValues[i] =
static_cast<T
>(
489 valuesStr[(i % 4) * 4 + (i >> 2)].toDouble(&success));
502 QString
toString(
int precision = 12, QChar separator =
' ')
const {
504 for (
unsigned l = 0; l < 4; ++l)
506 for (
unsigned c = 0; c < 4; ++c)
508 str.append(QString::number(
m_mat[c * 4 + l],
'f', precision));
509 if (c != 3) str.append(separator);
511 if (l != 3) str.append(
"\n");
522 if (!fp.open(QFile::WriteOnly | QFile::Text))
return false;
524 QTextStream stream(&fp);
525 stream.setRealNumberPrecision(precision);
526 stream.setRealNumberNotation(QTextStream::FixedNotation);
527 for (
unsigned i = 0; i < 4; ++i) {
532 return (fp.error() == QFile::NoError);
540 if (!fp.open(QFile::ReadOnly | QFile::Text))
return false;
542 QTextStream stream(&fp);
544 for (
unsigned i = 0; i < 4; ++i) {
546 stream >>
m_mat[i + 4];
547 stream >>
m_mat[i + 8];
548 stream >>
m_mat[i + 12];
551 return (fp.error() == QFile::NoError);
565 T cos_phi = cos(phi);
568 newRotMat.CC_MAT_R22 = newRotMat.CC_MAT_R33 = cos(theta);
569 newRotMat.CC_MAT_R32 = newRotMat.CC_MAT_R23 = sin(theta);
570 newRotMat.CC_MAT_R23 *=
static_cast<T
>(-1);
588 T cos_theta = cos(theta);
591 newRotMat.CC_MAT_R11 = newRotMat.CC_MAT_R33 = cos(phi);
592 newRotMat.CC_MAT_R31 = newRotMat.CC_MAT_R13 = sin(phi);
593 newRotMat.CC_MAT_R31 *=
static_cast<T
>(-1);
606 assert(Tr.
norm2() == 0);
629 for (
unsigned l = 0; l < 4; ++l) {
630 for (
unsigned c = 0; c < 4; ++c) {
631 if (
m_mat[c * 4 + l] !=
static_cast<T
>(l == c ? 1 : 0))
651 T cos_t = cos(alpha_rad);
652 T sin_t = sin(alpha_rad);
653 T inv_cos_t =
static_cast<T
>(1) - cos_t;
659 const T& l1 = uAxis3D.
x;
660 const T& l2 = uAxis3D.
y;
661 const T& l3 = uAxis3D.
z;
663 T l1_inv_cos_t = l1 * inv_cos_t;
664 T l3_inv_cos_t = l3 * inv_cos_t;
703 T c2 = cos(theta_rad);
707 T s2 = sin(theta_rad);
745 T cos_t = (trace - 1) / 2;
746 if (
fabs(cos_t) <= 1) {
747 alpha_rad = acos(cos_t);
757 T n2 = axis3D.
norm2();
783 T cos_theta = cos(theta_rad);
796 theta_rad =
static_cast<T
>(
M_PI_2);
799 theta_rad = -
static_cast<T
>(
M_PI_2);
911 return m_mat + (index << 2);
928 T* col =
m_mat + (index << 2);
939 T* col =
m_mat + (index << 2);
951 const T* B = mat.
m_mat;
954 for (
unsigned j = 0; j < 4; ++j, B += 4)
955 for (
unsigned i = 0; i < 4; ++i)
956 *C++ = A[i] * B[0] + A[i + 4] * B[1] + A[i + 8] * B[2] +
998 (*this) = (*this) * mat;
1033 return m_mat[(col << 2) + row];
1040 CCVector3 internal_vec(vec[0], vec[1], vec[2]);
1041 apply(internal_vec);
1042 vec[0] = internal_vec[0];
1043 vec[1] = internal_vec[1];
1044 vec[2] = internal_vec[2];
1049 inline void apply(
double vec[3])
const {
1050 CCVector3d internal_vec(vec[0], vec[1], vec[2]);
1051 apply(internal_vec);
1052 vec[0] = internal_vec[0];
1053 vec[1] = internal_vec[1];
1054 vec[2] = internal_vec[2];
1230 vec[0] =
static_cast<float>(
CC_MAT_R11) * vx +
1234 vec[1] =
static_cast<float>(
CC_MAT_R21) * vx +
1238 vec[2] =
static_cast<float>(
CC_MAT_R31) * vx +
1250 vec[0] =
static_cast<double>(
CC_MAT_R11) * vx +
1254 vec[1] =
static_cast<double>(
CC_MAT_R21) * vx +
1258 vec[2] =
static_cast<double>(
CC_MAT_R31) * vx +
1272 *
this += (vec - Rvec);
1305 if (s2 != 0 && s2 != 1) {
1355 assert(lineIndex < 4);
1356 m_mat[lineIndex] *= coef;
1357 m_mat[4 + lineIndex] *= coef;
1358 m_mat[8 + lineIndex] *= coef;
1359 m_mat[12 + lineIndex] *= coef;
1382 assert(rowIndex < 4);
1383 m_mat[rowIndex] *= coef;
1384 m_mat[4 + rowIndex] *= coef;
1385 m_mat[8 + rowIndex] *= coef;
1386 m_mat[12 + rowIndex] *= coef;
1394 assert(colIndex < 4);
1405 bool toFile(QFile& out,
short dataVersion)
const override {
1406 assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
1409 if (dataVersion < 20) {
1415 if (out.write(
reinterpret_cast<const char*
>(
m_mat),
1431 assert(in.isOpen() && (in.openMode() & QIODevice::ReadOnly));
1436 if (in.read(
reinterpret_cast<char*
>(
m_mat),
constexpr double M_PI_2
Pi/2.
QStringList qtCompatSplitRegex(const QString &str, const QString &pattern, Qt::SplitBehavior behavior=Qt::KeepEmptyParts)
4-Tuple structure (templated version)
void normalize()
Sets vector norm to unity.
Type dot(const Vector3Tpl &v) const
Dot product.
Type norm2() const
Returns vector square norm.
Vector3Tpl cross(const Vector3Tpl &v) const
Cross product.
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
A 4x4 'transformation' matrix (column major order)
float applyY(const Tuple4Tpl< float > &vec) const
Get the resulting transformation along Y dimension (float version)
ccGLMatrixTpl< T > & operator+=(const ccGLMatrixTpl< T > &mat)
(in place) Addition operator
ccGLMatrixTpl(const Eigen::Matrix< float, 4, 4 > &mat)
Copy Function.
QString toString(int precision=12, QChar separator=' ') const
Returns matrix as a string.
static ccGLMatrixTpl< T > FromEigenMatrix3(const Eigen::Matrix< T, 3, 3 > &mat)
Vector3Tpl< T > getTranslationAsVec3D() const
Returns a copy of the translation as a CCVector3.
void getParameters(T &phi_rad, T &theta_rad, T &psi_rad, Vector3Tpl< T > &t3D) const
Returns equivalent parameters: 3 rotation angles and a translation.
void toQuaternion(T q[]) const
Converts to a quaternion from a rotation matrix.
ccGLMatrixTpl< T > & operator-=(const Vector3Tpl< double > &Tr)
(in place) Backward translation operator (double version)
ccGLMatrixTpl< T > zRotation() const
Returns the rotation component around Z only.
void setColumn(unsigned index, const Vector3Tpl< T > &v)
Sets the content of a given column.
bool isSerializable() const override
Returns whether object is serializable of not.
void toAngleAxis(T &alpha_rad, Vector3Tpl< T > &axis3D) const
Returns equivalent parameters: a rotation axis and an angle.
T operator()(unsigned row, unsigned col) const
Returns the value at a given position.
void apply(Tuple4Tpl< float > &vec) const
Applies transformation to a 4D vector (in place) - float version.
virtual void toZero()
Clears matrix.
ccGLMatrixTpl(const Vector3Tpl< T > &X, const Vector3Tpl< T > &Y, const Vector3Tpl< T > &Z, const Vector3Tpl< T > &Tr)
Constructor from 4 columns (X,Y,Z,T)
static ccGLMatrixTpl< T > FromEigenMatrix(const Eigen::Matrix< double, 4, 4 > &mat)
bool fromFile(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads data from binary stream.
ccGLMatrixTpl< T > transposed() const
Returns transposed matrix.
ccGLMatrixTpl(const float *mat16f)
Constructor from a float GL matrix array.
void setTranslation(const Vector3Tpl< double > &Tr)
Sets translation (double version)
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
static ccGLMatrixTpl< T > FromQuaternion(const Tq q[])
Converts a quaternion to a rotation matrix.
static Eigen::Matrix< T, 3, 3 > ToEigenMatrix3(const ccGLMatrixTpl< double > &mat)
static ccGLMatrixTpl< T > FromToRotation(const Vector3Tpl< T > &from, const Vector3Tpl< T > &to)
Creates a transformation matrix that rotates a vector to another.
void applyRotation(float vec[3]) const
Applies rotation only to a 3D vector (in place) - float version.
void apply(Vector3Tpl< float > &vec) const
Applies transformation to a 3D vector (in place) - float version.
ccGLMatrixTpl(const Eigen::Matrix< double, 4, 4 > &mat)
ccGLMatrixTpl< T > & operator-=(const Vector3Tpl< float > &Tr)
(in place) Backward translation operator (float version)
void applyRotation(double vec[3]) const
Applies rotation only to a 3D vector (in place) - float version.
void setColumn(unsigned index, const Tuple4Tpl< T > &v)
Sets the content of a given column.
float applyX(const Tuple4Tpl< float > &vec) const
Get the resulting transformation along X dimension (float version)
ccGLMatrixTpl< T > & operator=(const ccGLMatrixTpl< T > &mat)
Copy assignment operator.
virtual bool isIdentity() const
Returns whether this matrix is equal to identity.
void scaleRow(unsigned rowIndex, T coef)
Scales one row of the matrix.
const T * data() const
Returns a const pointer to internal data.
void initFromParameters(T phi_rad, T theta_rad, T psi_rad, const Vector3Tpl< T > &t3D)
Inits transformation from 3 rotation angles and a translation.
T * getTranslation()
Retruns a pointer to internal translation.
T * data()
Returns a pointer to internal data.
void clearTranslation()
Clears translation.
const T * getTranslation() const
Retruns a const pointer to internal translation.
Vector3Tpl< float > operator*(const Vector3Tpl< float > &vec) const
Multiplication by a vector operator (float version)
float applyW(const Tuple4Tpl< float > &vec) const
Get the resulting transformation along the 4th dimension (float version)
ccGLMatrixTpl(const Eigen::Matrix< float, 3, 3 > &mat)
void setTranslation(const float Tr[3])
Sets translation from a float array.
void shiftRotationCenter(const Vector3Tpl< T > &vec)
Shifts rotation center.
float applyY(const Vector3Tpl< float > &vec) const
Get the resulting transformation along Y dimension (float version)
bool toFile(QFile &out, short dataVersion) const override
Saves data to binary stream.
Tuple4Tpl< float > operator*(const Tuple4Tpl< float > &vec) const
Multiplication by a 4D vector operator (float version)
static ccGLMatrixTpl< T > FromViewDirAndUpDir(const Vector3Tpl< T > &forward, const Vector3Tpl< T > &up)
Generates a 'viewing' matrix from a looking vector and a 'up' direction.
static Eigen::Matrix< T, 4, 1 > NormalizeQuaternion(const Eigen::Matrix< T, 4, 1 > &qvec)
Converts a quaternion to a rotation matrix.
ccGLMatrixTpl< T > & operator+=(const Vector3Tpl< double > &Tr)
(in place) Forward translation operator (double version)
void invert()
Inverts transformation.
void scaleColumn(unsigned colIndex, T coef)
Scales one column of the matrix.
ccGLMatrixTpl< T > & operator-=(const ccGLMatrixTpl< T > &mat)
(in place) Difference operator
Tuple4Tpl< double > operator*(const Tuple4Tpl< double > &vec) const
Multiplication by a 4D vector operator (double version)
double applyX(const Vector3Tpl< double > &vec) const
Get the resulting transformation along X dimension (double version)
ccGLMatrixTpl< T > operator*(const ccGLMatrixTpl< T > &mat) const
Multiplication by a matrix operator.
double applyY(const Tuple4Tpl< double > &vec) const
Get the resulting transformation along Y dimension (double version)
void apply(double vec[3]) const
Applies transformation to a 3D vector (in place) - double version.
void setRotation(const float Rt[9])
Sets Rotation from a float array.
static ccGLMatrixTpl Interpolate(T coef, const ccGLMatrixTpl< T > &glMat1, const ccGLMatrixTpl< T > &glMat2)
Interpolates two matrices at relative position 'coef'.
Vector3Tpl< double > operator*(const Vector3Tpl< double > &vec) const
Multiplication by a vector operator (double version)
void scaleLine(unsigned lineIndex, T coef)
Scales one line of the matrix.
static Eigen::Matrix< T, 4, 4 > ToEigenMatrix4(const ccGLMatrixTpl< double > &mat)
void applyRotation(Vector3Tpl< double > &vec) const
Applies rotation only to a 3D vector (in place) - double version.
static ccGLMatrixTpl< T > QuaternionToRotationMatrix(const Tuple4Tpl< T > &qvec)
Converts a quaternion to a rotation matrix.
virtual bool fromAsciiFile(QString filename)
Loads matrix from an ASCII file.
ccGLMatrixTpl(const double *mat16d)
Constructor from a double GL matrix array.
float applyZ(const Tuple4Tpl< float > &vec) const
Get the resulting transformation along Z dimension (float version)
void setRotation(const double Rt[9])
Sets Rotation from a double array.
ccGLMatrixTpl< T > inverse() const
Returns inverse transformation.
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
void setTranslation(const double Tr[3])
Sets translation from a double array.
float applyX(const Vector3Tpl< float > &vec) const
Get the resulting transformation along X dimension (float version)
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
void scaleRotation(T coef)
Scales the rotation part of the matrix.
ccGLMatrixTpl< T > & operator+=(const Vector3Tpl< float > &Tr)
(in place) Forward translation operator (float version)
Vector3Tpl< T > getColumnAsVec3D(unsigned index) const
Returns a copy of a given column as a CCVector3.
void toEulerAngle(T &rz, T &ry, T &rx) const
Returns equivalent parameters: 3 rotation angles.
const T * getColumn(unsigned index) const
Returns a const pointer to a given column.
void apply(Tuple4Tpl< double > &vec) const
Applies transformation to a 3D vector (in place) - double version.
double applyY(const Vector3Tpl< double > &vec) const
Get the resulting transformation along Y dimension (double version)
ccGLMatrixTpl< T > & operator=(const Eigen::Matrix< float, 3, 3 > &mat)
static Eigen::Matrix< T, 3, 3 > QuaternionToRotationMatrix(const Eigen::Matrix< T, 4, 1 > &qvec)
Converts a quaternion to a rotation matrix.
void scale(T coef)
Scales the whole matrix.
static ccGLMatrixTpl< T > FromString(const QString &matText, bool &success)
Converts a 'text' matrix to a ccGLMatrix.
ccGLMatrixTpl()
Default constructor.
short minimumFileVersion() const override
Returns the minimum file version required to save this instance.
void apply(Vector3Tpl< double > &vec) const
Applies transformation to a 3D vector (in place) - double version.
ccGLMatrixTpl< T > yRotation() const
Returns the rotation component around Y only.
ccGLMatrixTpl< T > & operator=(const Eigen::Matrix< double, 3, 3 > &mat)
void transpose()
Transposes matrix (in place)
ccGLMatrixTpl(const Eigen::Matrix< double, 3, 3 > &mat)
double applyZ(const Vector3Tpl< double > &vec) const
Get the resulting transformation along Z dimension (double version)
double applyX(const Tuple4Tpl< double > &vec) const
Get the resulting transformation along X dimension (double version)
void initFromParameters(T alpha_rad, const Vector3Tpl< T > &axis3D, const Vector3Tpl< T > &t3D)
Inits transformation from a rotation axis, an angle and a translation.
T m_mat[OPENGL_MATRIX_SIZE]
Internal 4x4 GL-style matrix data.
ccGLMatrixTpl(const ccGLMatrixTpl< T > &mat)
Copy constructor.
virtual void toIdentity()
Sets matrix to identity.
ccGLMatrixTpl< T > & operator=(const Eigen::Matrix< float, 4, 4 > &mat)
Assignment Function.
double applyW(const Tuple4Tpl< double > &vec) const
T * getColumn(unsigned index)
Returns a pointer to a given column.
ccGLMatrixTpl< T > & operator=(const Eigen::Matrix< double, 4, 4 > &mat)
double applyZ(const Tuple4Tpl< double > &vec) const
Get the resulting transformation along Z dimension (double version)
ccGLMatrixTpl< T > & operator*=(const ccGLMatrixTpl< T > &mat)
(in place) Multiplication operator
static Eigen::Matrix< T, 3, 3 > ToEigenMatrix3(const ccGLMatrixTpl< float > &mat)
float applyZ(const Vector3Tpl< float > &vec) const
Get the resulting transformation along Z dimension (float version)
static Eigen::Matrix< T, 4, 4 > ToEigenMatrix4(const ccGLMatrixTpl< float > &mat)
void getParameters(T &alpha_rad, Vector3Tpl< T > &axis3D, Vector3Tpl< T > &t3D) const
ccGLMatrixTpl< T > xRotation() const
Returns the rotation component around X only.
virtual bool toAsciiFile(QString filename, int precision=12) const
Saves matrix to an ASCII file.
Serializable object interface.
static bool CorruptError()
Sends a custom error message (corrupted file) and returns 'false'.
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
__host__ __device__ float2 fabs(float2 v)
static const unsigned OPENGL_MATRIX_SIZE
Model view matrix size (OpenGL)
constexpr Qt::SplitBehavior SkipEmptyParts
QTextStream & endl(QTextStream &stream)
bool GreaterThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.