 |
Dem Bones
1.2.0
Skinning Decomposition Library
|
Go to the documentation of this file.
13 #include <Eigen/Geometry>
15 #ifndef DEM_BONES_MAT_BLOCKS
17 #define DEM_BONES_DEM_BONES_EXT_MAT_BLOCKS_UNDEFINED
30 template<
class _Scalar,
class _AniMeshScalar>
33 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
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>;
138 int root=computeRoot();
139 parent=Eigen::VectorXi::Constant(
nB, root);
141 }
else parent=Eigen::VectorXi::Constant(
nB, -1);
148 lr.resize(nFs*3,
nB);
149 lt.resize(nFs*3,
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);
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();
166 else lb=
preMulInv.blk4(s, j)*gb.blk4(0,
parent(j)).inverse()*gb.blk4(0, j);
168 Vector3 curRot=Vector3::Zero();
169 toRot(invOM*lb.template topLeftCorner<3, 3>(), curRot, ro);
171 lbt.col(j)=lb.template topRightCorner<3, 1>();
174 for (
int k=0; k<nFs; k++) {
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>();
194 void computeCentroids(
int s,
MatrixX& b) {
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);
208 void computeBind(
int s,
MatrixX& b) {
209 if (
bind.size()==0) {
210 lockM=Eigen::VectorXi::Zero(
nB);
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;
219 b=
bind.block(4*s, 0, 4, 4*
nB);
227 #pragma omp parallel for
228 for (
int j=0; j<
nB; j++) {
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();
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();
251 for (
int fx=-1; fx<=1; fx+=2)
252 for (_Scalar sx=-2*EIGEN_PI; sx<2.1*EIGEN_PI; sx+=EIGEN_PI) {
254 for (
int fy=-1; fy<=1; fy+=2)
255 for (_Scalar sy=-2*EIGEN_PI; sy<2.1*EIGEN_PI; sy+=EIGEN_PI) {
257 for (
int fz=-1; fz<=1; fz+=2)
258 for (_Scalar sz=-2*EIGEN_PI; sz<2.1*EIGEN_PI; sz+=EIGEN_PI) {
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();
279 #ifdef DEM_BONES_DEM_BONES_EXT_MAT_BLOCKS_UNDEFINED
284 #undef DEM_BONES_MAT_BLOCKS
287 #undef rotMatFromEuler
MatrixX m
Bone transformations, size = [4*nF*4, 4*nB], m.blk4(k, j) is the 4*4 relative transformation matrix o...
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > VectorX
DemBonesExt()
Constructor and setting default parameters.
Extended class to handle hierarchical skeleton with local rotations/translations and bind matrices.
int nV
Number of vertices, typically indexed by i.
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
_Scalar transAffineNorm
[parameter] p-norm for bone translations affinity soft constraint, default = 4.0
Eigen::Matrix< _Scalar, 4, 1 > Vector4
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 ...
const int & iterWeights
[zero indexed, read only] Current weights update iteration number that can be used for callback funct...
void computeRTB(int s, MatrixX &lr, MatrixX <, MatrixX &gb, MatrixX &lbr, MatrixX &lbt, bool degreeRot=true)
Local rotations, translations and global bind matrices of a subject.
Eigen::SparseMatrix< _Scalar > SparseMatrix
Eigen::VectorXi subjectID
Subject index of the frame, size = nF, subjectID(k)=s, where fStart(s) <= k < fStart(s+1)
Defines some macros to access sub-blocks of packing transformation/position matrices for convenience.
Eigen::VectorXi fStart
Start frame indices, size = nS+1, fStart(s), fStart(s+1) are data frames for subject s.
MatrixX preMulInv
Inverse pre-multiplication matrices, [size] = [4*nS, 4*nB], preMulInv.block(4*s, 4*j,...
MatrixX orient
Orientations of bones, [size] = [3*nS, nB], orient.col(j).segment<3>(3*s) is the(rx,...
void clear()
Clear all data.
Eigen::Matrix< _Scalar, 3, 3 > Matrix3
Eigen::VectorXd fTime
Timestamps for bone transformations m, [size] = nS, fTime(k) is the timestamp of frame k.
int nS
Number of subjects, typically indexed by s.
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > VectorX
Eigen::Matrix< _Scalar, 3, 1 > Vector3
MatrixX bind
Original bind pre-matrix, [size] = [4*nS, 4*nB], bind.block(4*s, 4*j, 4, 4) is the global bind matrix...
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...
int nF
Number of total frames, typically indexed by k, nF = fStart(nS)
int bindUpdate
Bind transformation update, 0=keep original, 1=set translations to p-norm centroids (using transAffin...
Eigen::Matrix< _Scalar, 3, 1 > Vector3
Eigen::Triplet< _Scalar > Triplet
SparseMatrix w
Skinning weights, size = [nB, nV], w.col(i) are the skinning weights of vertex i, w(j,...
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
int nB
Number of bones, typically indexed by j.
Eigen::Matrix< _Scalar, 4, 4 > Matrix4
std::vector< std::string > boneName
Name of bones, [size] = nB, boneName(j) is the name bone of j.
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...
Smooth skinning decomposition with rigid bones and sparse, convex weights.
Eigen::MatrixXi rotOrder
Rotation order, [size] = [3*nS, nB], rotOrder.col(j).segment<3>(3*s) is the rotation order of bone j ...
Eigen::VectorXi lockM
Bone transformation lock control, size = nB, lockM(j) is the amount of input transformations will be ...
Eigen::Matrix< _Scalar, 3, 3 > Matrix3
void clear()
Clear all data.