Dem Bones  1.2.0
Skinning Decomposition Library
DemBonesExt.h
Go to the documentation of this file.
1 // Dem Bones - Skinning Decomposition Library //
3 // Copyright (c) 2019, Electronic Arts. All rights reserved. //
5 
6 
7 
8 #ifndef DEM_BONES_EXT
9 #define DEM_BONES_EXT
10 
11 #include "DemBones.h"
12 
13 #include <Eigen/Geometry>
14 
15 #ifndef DEM_BONES_MAT_BLOCKS
16 #include "MatBlocks.h"
17 #define DEM_BONES_DEM_BONES_EXT_MAT_BLOCKS_UNDEFINED
18 #endif
19 
20 namespace Dem
21 {
22 
30 template<class _Scalar, class _AniMeshScalar>
31 class DemBonesExt: public DemBones<_Scalar, _AniMeshScalar> {
32 public:
33  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
34 
35  using MatrixX=Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic>;
36  using Matrix4=Eigen::Matrix<_Scalar, 4, 4>;
37  using Matrix3=Eigen::Matrix<_Scalar, 3, 3>;
38  using VectorX=Eigen::Matrix<_Scalar, Eigen::Dynamic, 1>;
39  using Vector4=Eigen::Matrix<_Scalar, 4, 1>;
40  using Vector3=Eigen::Matrix<_Scalar, 3, 1>;
41  using SparseMatrix=Eigen::SparseMatrix<_Scalar>;
42  using Triplet=Eigen::Triplet<_Scalar>;
43 
54 
68 
72 
74  Eigen::VectorXd fTime;
75 
77  std::vector<std::string> boneName;
78 
80  Eigen::VectorXi parent;
81 
84 
87 
89  Eigen::MatrixXi rotOrder;
90 
93 
96 
100  clear();
101  }
102 
105  void clear() {
106  fTime.resize(0);
107  boneName.resize(0);
108  parent.resize(0);
109  bind.resize(0, 0);
110  preMulInv.resize(0, 0);
111  rotOrder.resize(0, 0);
112  orient.resize(0, 0);
114  }
115 
133  void computeRTB(int s, MatrixX& lr, MatrixX& lt, MatrixX& gb, MatrixX& lbr, MatrixX& lbt, bool degreeRot=true) {
134  computeBind(s, gb);
135 
136  if (parent.size()==0) {
137  if (bindUpdate==2) {
138  int root=computeRoot();
139  parent=Eigen::VectorXi::Constant(nB, root);
140  parent(root)=-1;
141  } else parent=Eigen::VectorXi::Constant(nB, -1);
142  }
143  if (preMulInv.size()==0) preMulInv=MatrixX::Identity(4, 4).replicate(nS, nB);
144  if (rotOrder.size()==0) rotOrder=Eigen::Vector3i(0, 1, 2).replicate(nS, nB);
145  if (orient.size()==0) orient=MatrixX::Zero(3*nS, nB);
146 
147  int nFs=fStart(s+1)-fStart(s);
148  lr.resize(nFs*3, nB);
149  lt.resize(nFs*3, nB);
150  lbr.resize(3, nB);
151  lbt.resize(3, nB);
152 
153  MatrixX lm(4*nFs, 4*nB);
154  #pragma omp parallel for
155  for (int j=0; j<nB; j++) {
156  Eigen::Vector3i ro=rotOrder.col(j).template segment<3>(s*3);
157 
158  Vector3 ov=orient.vec3(s, j)*EIGEN_PI/180;
159  Matrix3 invOM=Matrix3(Eigen::AngleAxis<_Scalar>(ov(ro(2)), Vector3::Unit(ro(2))))*
160  Eigen::AngleAxis<_Scalar>(ov(ro(1)), Vector3::Unit(ro(1)))*
161  Eigen::AngleAxis<_Scalar>(ov(ro(0)), Vector3::Unit(ro(0)));
162  invOM.transposeInPlace();
163 
164  Matrix4 lb;
165  if (parent(j)==-1) lb=preMulInv.blk4(s, j)*gb.blk4(0, j);
166  else lb=preMulInv.blk4(s, j)*gb.blk4(0, parent(j)).inverse()*gb.blk4(0, j);
167 
168  Vector3 curRot=Vector3::Zero();
169  toRot(invOM*lb.template topLeftCorner<3, 3>(), curRot, ro);
170  lbr.col(j)=curRot;
171  lbt.col(j)=lb.template topRightCorner<3, 1>();
172 
173  Matrix4 lm;
174  for (int k=0; k<nFs; k++) {
175  if (parent(j)==-1) lm=preMulInv.blk4(s, j)*m.blk4(k+fStart(s), j)*gb.blk4(0, j);
176  else lm=preMulInv.blk4(s, j)*(m.blk4(k+fStart(s), parent(j))*gb.blk4(0, parent(j))).inverse()*m.blk4(k+fStart(s), j)*gb.blk4(0, j);
177  toRot(invOM*lm.template topLeftCorner<3, 3>(), curRot, ro);
178  lr.vec3(k, j)=curRot;
179  lt.vec3(k, j)=lm.template topRightCorner<3, 1>();
180  }
181  }
182 
183  if (degreeRot) {
184  lr*=180/EIGEN_PI;
185  lbr*=180/EIGEN_PI;
186  }
187  }
188 
189 private:
194  void computeCentroids(int s, MatrixX& b) {
195  MatrixX c=MatrixX::Zero(4, nB);
196  for (int i=0; i<nV; i++)
197  for (typename SparseMatrix::InnerIterator it(w, i); it; ++it)
198  c.col(it.row())+=pow(it.value(), transAffineNorm)*u.vec3(s, i).homogeneous();
199  for (int j=0; j<nB; j++)
200  if ((c(3, j)!=0)&&(lockM(j)==0)) b.transVec(0, j)=c.col(j).template head<3>()/c(3, j);
201  }
202 
208  void computeBind(int s, MatrixX& b) {
209  if (bind.size()==0) {
210  lockM=Eigen::VectorXi::Zero(nB);
211  bind.resize(nS*4, nB*4);
212  for (int k=0; k<nS; k++) {
213  b=MatrixX::Identity(4, 4).replicate(1, nB);
214  computeCentroids(k, b);
215  bind.block(4*s, 0, 4, 4*nB)=b;
216  }
217  }
218 
219  b=bind.block(4*s, 0, 4, 4*nB);
220  if (bindUpdate>=1) computeCentroids(s, b);
221  }
222 
225  int computeRoot() {
226  VectorX err(nB);
227  #pragma omp parallel for
228  for (int j=0; j<nB; j++) {
229  double ej=0;
230  for (int i=0; i<nV; i++)
231  for (int k=0; k<nF; k++) ej+=(m.rotMat(k, j)*u.vec3(subjectID(k), i)+m.transVec(k, j)-v.vec3(k, i).template cast<_Scalar>()).squaredNorm();
232  err(j)=ej;
233  }
234  int rj;
235  err.minCoeff(&rj);
236  return rj;
237  }
238 
245  void toRot(const Matrix3& rMat, Vector3& curRot, const Eigen::Vector3i& ro, _Scalar eps=_Scalar(1e-10)) {
246  Vector3 r0=rMat.eulerAngles(ro(2), ro(1), ro(0)).reverse();
247  _Scalar gMin=(r0-curRot).squaredNorm();
248  Vector3 rMin=r0;
249  Vector3 r;
250  Matrix3 tmpMat;
251  for (int fx=-1; fx<=1; fx+=2)
252  for (_Scalar sx=-2*EIGEN_PI; sx<2.1*EIGEN_PI; sx+=EIGEN_PI) {
253  r(0)=fx*r0(0)+sx;
254  for (int fy=-1; fy<=1; fy+=2)
255  for (_Scalar sy=-2*EIGEN_PI; sy<2.1*EIGEN_PI; sy+=EIGEN_PI) {
256  r(1)=fy*r0(1)+sy;
257  for (int fz=-1; fz<=1; fz+=2)
258  for (_Scalar sz=-2*EIGEN_PI; sz<2.1*EIGEN_PI; sz+=EIGEN_PI) {
259  r(2)=fz*r0(2)+sz;
260  tmpMat=Matrix3(Eigen::AngleAxis<_Scalar>(r(ro(2)), Vector3::Unit(ro(2))))*
261  Eigen::AngleAxis<_Scalar>(r(ro(1)), Vector3::Unit(ro(1)))*
262  Eigen::AngleAxis<_Scalar>(r(ro(0)), Vector3::Unit(ro(0)));
263  if ((tmpMat-rMat).squaredNorm()<eps) {
264  _Scalar tmp=(r-curRot).squaredNorm();
265  if (tmp<gMin) {
266  gMin=tmp;
267  rMin=r;
268  }
269  }
270  }
271  }
272  }
273  curRot=rMin;
274  }
275 };
276 
277 }
278 
279 #ifdef DEM_BONES_DEM_BONES_EXT_MAT_BLOCKS_UNDEFINED
280 #undef blk4
281 #undef rotMat
282 #undef transVec
283 #undef vec3
284 #undef DEM_BONES_MAT_BLOCKS
285 #endif
286 
287 #undef rotMatFromEuler
288 
289 #endif
Dem::DemBones::m
MatrixX m
Bone transformations, size = [4*nF*4, 4*nB], m.blk4(k, j) is the 4*4 relative transformation matrix o...
Definition: DemBones.h:139
Dem::DemBonesExt::VectorX
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > VectorX
Definition: DemBonesExt.h:38
Dem::DemBonesExt::DemBonesExt
DemBonesExt()
Constructor and setting default parameters.
Definition: DemBonesExt.h:99
Dem::DemBonesExt
Extended class to handle hierarchical skeleton with local rotations/translations and bind matrices.
Definition: DemBonesExt.h:31
Dem::DemBones::nV
int nV
Number of vertices, typically indexed by i.
Definition: DemBones.h:114
Dem::DemBonesExt::MatrixX
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Definition: DemBonesExt.h:35
Dem
Definition: ConvexLS.h:15
Dem::DemBones::transAffineNorm
_Scalar transAffineNorm
[parameter] p-norm for bone translations affinity soft constraint, default = 4.0
Definition: DemBones.h:90
Dem::DemBones::Vector4
Eigen::Matrix< _Scalar, 4, 1 > Vector4
Definition: DemBones.h:74
DemBones.h
Dem::DemBones::u
MatrixX u
Geometry at the rest poses, size = [3*nS, nV], u.col(i).segment(3*s, 3) is the rest pose of vertex i ...
Definition: DemBones.h:128
Dem::DemBones::iterWeights
const int & iterWeights
[zero indexed, read only] Current weights update iteration number that can be used for callback funct...
Definition: DemBones.h:157
Dem::DemBonesExt::computeRTB
void computeRTB(int s, MatrixX &lr, MatrixX &lt, MatrixX &gb, MatrixX &lbr, MatrixX &lbt, bool degreeRot=true)
Local rotations, translations and global bind matrices of a subject.
Definition: DemBonesExt.h:133
Dem::DemBones::SparseMatrix
Eigen::SparseMatrix< _Scalar > SparseMatrix
Definition: DemBones.h:76
Dem::DemBones::subjectID
Eigen::VectorXi subjectID
Subject index of the frame, size = nF, subjectID(k)=s, where fStart(s) <= k < fStart(s+1)
Definition: DemBones.h:125
MatBlocks.h
Defines some macros to access sub-blocks of packing transformation/position matrices for convenience.
Dem::DemBones::fStart
Eigen::VectorXi fStart
Start frame indices, size = nS+1, fStart(s), fStart(s+1) are data frames for subject s.
Definition: DemBones.h:123
Dem::DemBonesExt::preMulInv
MatrixX preMulInv
Inverse pre-multiplication matrices, [size] = [4*nS, 4*nB], preMulInv.block(4*s, 4*j,...
Definition: DemBonesExt.h:86
Dem::DemBonesExt::orient
MatrixX orient
Orientations of bones, [size] = [3*nS, nB], orient.col(j).segment<3>(3*s) is the(rx,...
Definition: DemBonesExt.h:92
Dem::DemBonesExt::clear
void clear()
Clear all data.
Definition: DemBonesExt.h:105
Dem::DemBonesExt::Matrix3
Eigen::Matrix< _Scalar, 3, 3 > Matrix3
Definition: DemBonesExt.h:37
Dem::DemBonesExt::fTime
Eigen::VectorXd fTime
Timestamps for bone transformations m, [size] = nS, fTime(k) is the timestamp of frame k.
Definition: DemBonesExt.h:74
Dem::DemBones::nS
int nS
Number of subjects, typically indexed by s.
Definition: DemBones.h:118
Dem::DemBones::VectorX
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > VectorX
Definition: DemBones.h:73
Dem::DemBonesExt::Vector3
Eigen::Matrix< _Scalar, 3, 1 > Vector3
Definition: DemBonesExt.h:40
Dem::DemBonesExt::bind
MatrixX bind
Original bind pre-matrix, [size] = [4*nS, 4*nB], bind.block(4*s, 4*j, 4, 4) is the global bind matrix...
Definition: DemBonesExt.h:83
Dem::DemBonesExt::parent
Eigen::VectorXi parent
Parent bone index, [size] = nB, parent(j) is the index of parent bone of j, parent(j) = -1 if j has n...
Definition: DemBonesExt.h:80
Dem::DemBones::nF
int nF
Number of total frames, typically indexed by k, nF = fStart(nS)
Definition: DemBones.h:120
Dem::DemBonesExt::bindUpdate
int bindUpdate
Bind transformation update, 0=keep original, 1=set translations to p-norm centroids (using transAffin...
Definition: DemBonesExt.h:95
Dem::DemBones::Vector3
Eigen::Matrix< _Scalar, 3, 1 > Vector3
Definition: DemBones.h:75
Dem::DemBones::Triplet
Eigen::Triplet< _Scalar > Triplet
Definition: DemBones.h:77
Dem::DemBones::w
SparseMatrix w
Skinning weights, size = [nB, nV], w.col(i) are the skinning weights of vertex i, w(j,...
Definition: DemBones.h:131
Dem::DemBones::MatrixX
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Definition: DemBones.h:70
Dem::DemBones::nB
int nB
Number of bones, typically indexed by j.
Definition: DemBones.h:116
Dem::DemBones::Matrix4
Eigen::Matrix< _Scalar, 4, 4 > Matrix4
Definition: DemBones.h:71
Dem::DemBonesExt::boneName
std::vector< std::string > boneName
Name of bones, [size] = nB, boneName(j) is the name bone of j.
Definition: DemBonesExt.h:77
Dem::DemBones::v
Eigen::Matrix< _AniMeshScalar, Eigen::Dynamic, Eigen::Dynamic > v
Animated mesh sequence, size = [3*nF, nV], v.col(i).segment(3*k, 3) is the position of vertex i at fr...
Definition: DemBones.h:145
Dem::DemBones
Smooth skinning decomposition with rigid bones and sparse, convex weights.
Definition: DemBones.h:66
Dem::DemBonesExt::rotOrder
Eigen::MatrixXi rotOrder
Rotation order, [size] = [3*nS, nB], rotOrder.col(j).segment<3>(3*s) is the rotation order of bone j ...
Definition: DemBonesExt.h:89
Dem::DemBones::lockM
Eigen::VectorXi lockM
Bone transformation lock control, size = nB, lockM(j) is the amount of input transformations will be ...
Definition: DemBones.h:142
Dem::DemBones::Matrix3
Eigen::Matrix< _Scalar, 3, 3 > Matrix3
Definition: DemBones.h:72
Dem::DemBones::clear
void clear()
Clear all data.
Definition: DemBones.h:161