1+ /* *
2+ This file is part of mesh-deform.
3+
4+ Copyright(C) 2016 Christoph Heindl
5+ All rights reserved.
6+
7+ This software may be modified and distributed under the terms
8+ of the BSD license.See the LICENSE file for details.
9+ */
10+
11+ #ifndef DEFORM_TRAJECTORY_H
12+ #define DEFORM_TRAJECTORY_H
13+
14+ #include < Eigen/Dense>
15+ #include < Eigen/Geometry>
16+ #include < Eigen/StdVector>
17+
18+ #ifdef _WIN32
19+ #pragma warning (push)
20+ #pragma warning (disable : 4244)
21+ #endif
22+
23+ #include < sophus/sophus.hpp>
24+ #include < sophus/se3.hpp>
25+
26+ #ifdef _WIN32
27+ #pragma warning (pop)
28+ #endif
29+
30+ namespace deform {
31+
32+ template <class PrecisionType = typename MeshType::Scalar>
33+ class TrajectorySE3 {
34+ public:
35+
36+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
37+
38+ /* * Floating point precision used in calculations. */
39+ typedef PrecisionType Scalar;
40+
41+ /* * Group type */
42+ typedef Sophus::SE3Group<Scalar> SE3Group;
43+
44+ /* * Transformation matrix type. */
45+ typedef Eigen::Transform<Scalar, 3 , Eigen::Affine> Transform;
46+
47+ /* *
48+ Construct empty trajectory
49+ */
50+ TrajectorySE3 (Scalar timeStep)
51+ :_timeStep(timeStep)
52+ {
53+ _C <<
54+ 6 , 0 , 0 , 0 ,
55+ 5 , 3 , -3 , 1 ,
56+ 1 , 3 , 3 , -2 ,
57+ 0 , 0 , 0 , 1 ;
58+ _C *= Scalar (1 ) / 6 ;
59+ }
60+
61+ void addKeyframe (const Transform &transform) {
62+ _keyframes.push_back (transform);
63+ const size_t n = _keyframes.size ();
64+
65+ if (n > 1 ) {
66+ Transform delta = _keyframes[n - 2 ].inverse (Eigen::Isometry) * _keyframes[n - 1 ];
67+
68+ SE3Group g (delta.matrix ());
69+ _omegas.push_back (g.log ());
70+
71+ if (n == 2 ) {
72+ Transform deltainv = delta.inverse (Eigen::Isometry);
73+ SE3Group g (deltainv.matrix ());
74+ _omegas[0 ] = g.log ();
75+ }
76+ } else {
77+ _omegas.push_back (SE3Group::Tangent::Zero ()); // Will be fixed when second keyframe is given.
78+ }
79+ }
80+
81+ Transform operator ()(Scalar time) const {
82+
83+ const Scalar t0 (0 );
84+ const Scalar s = (time - t0) / _timeStep;
85+
86+ const int i = static_cast <int >(std::floor (s));
87+ eigen_assert (i >= 0 );
88+
89+ const Scalar u = s - Scalar (i);
90+ const Eigen::Matrix<Scalar, 4 , 1 > b = _C * Eigen::Matrix<Scalar, 4 , 1 >(Scalar (1 ), u, u*u, u*u*u);
91+
92+ Transform trans = previousTransform (i);
93+ for (int j = 1 ; j < 4 ; ++j) {
94+ SE3Group::Tangent o = omega (i + j);
95+ std::cout << " omega is " << o.transpose () << std::endl;
96+ std::cout << " b is" << b (j) << std::endl;
97+ std::cout << " omega * b is " << (b (j) * o).transpose () << std::endl;
98+
99+ trans = trans * SE3Group::exp (b (j) * o).affine3 ();
100+ }
101+
102+ return trans;
103+ }
104+
105+ private:
106+
107+ typename SE3Group::Tangent omega (int idx) const {
108+ if ((size_t )idx < _omegas.size ())
109+ return _omegas[idx];
110+ else
111+ return _omegas.back ();
112+ }
113+
114+ Transform previousTransform (int idx) const {
115+ if (idx == 0 )
116+ return SE3Group::exp (_omegas[0 ]).affine3 () * _keyframes[0 ];
117+ else
118+ return _keyframes[idx - 1 ];
119+ }
120+
121+ Scalar _timeStep;
122+ std::vector<Transform, Eigen::aligned_allocator<Transform> > _keyframes;
123+ std::vector<typename SE3Group::Tangent, Eigen::aligned_allocator<typename SE3Group::Tangent> > _omegas;
124+ Eigen::Matrix<Scalar, 4 , 4 > _C;
125+ };
126+ }
127+
128+ #endif
0 commit comments