1111#include " momentum/character/blend_shape_skinning.h"
1212#include " momentum/character/character.h"
1313#include " momentum/character/linear_skinning.h"
14+ #include " momentum/character/mesh_state.h"
1415#include " momentum/character/skeleton.h"
1516#include " momentum/character/skeleton_state.h"
1617#include " momentum/character_solver/error_function_utils.h"
@@ -28,9 +29,6 @@ VertexVertexDistanceErrorFunctionT<T>::VertexVertexDistanceErrorFunctionT(
2829 character_ (character) {
2930 MT_CHECK (static_cast <bool >(character.mesh ));
3031 MT_CHECK (static_cast <bool >(character.skinWeights ));
31-
32- this ->restMesh_ = std::make_unique<MeshT<T>>(character.mesh ->template cast <T>());
33- this ->posedMesh_ = std::make_unique<MeshT<T>>(character.mesh ->template cast <T>());
3432}
3533
3634template <typename T>
@@ -59,16 +57,16 @@ template <typename T>
5957double VertexVertexDistanceErrorFunctionT<T>::getError(
6058 const ModelParametersT<T>& modelParameters,
6159 const SkeletonStateT<T>& state,
62- const MeshStateT<T>& /* meshState */ ) {
60+ const MeshStateT<T>& meshState) {
6361 MT_PROFILE_FUNCTION ();
6462
65- updateMeshes (modelParameters, state );
63+ MT_CHECK_NOTNULL (meshState. posedMesh_ );
6664
6765 double error = 0.0 ;
6866
6967 for (const auto & constraint : constraints_) {
70- const auto & pos1 = posedMesh_->vertices [constraint.vertexIndex1 ];
71- const auto & pos2 = posedMesh_->vertices [constraint.vertexIndex2 ];
68+ const auto & pos1 = meshState. posedMesh_ ->vertices [constraint.vertexIndex1 ];
69+ const auto & pos2 = meshState. posedMesh_ ->vertices [constraint.vertexIndex2 ];
7270
7371 const T actualDistance = (pos1 - pos2).norm ();
7472 const T distanceDiff = actualDistance - constraint.targetDistance ;
@@ -79,48 +77,21 @@ double VertexVertexDistanceErrorFunctionT<T>::getError(
7977 return error * this ->weight_ ;
8078}
8179
82- template <typename T>
83- void VertexVertexDistanceErrorFunctionT<T>::updateMeshes(
84- const ModelParametersT<T>& modelParameters,
85- const SkeletonStateT<T>& state) {
86- MT_PROFILE_FUNCTION ();
87-
88- // Update rest mesh with blend shapes if present
89- bool doUpdateNormals = false ;
90- if (this ->character_ .blendShape ) {
91- const BlendWeightsT<T> blendWeights =
92- extractBlendWeights (this ->parameterTransform_ , modelParameters);
93- this ->character_ .blendShape ->computeShape (blendWeights, this ->restMesh_ ->vertices );
94- doUpdateNormals = true ;
95- }
96-
97- if (doUpdateNormals) {
98- this ->restMesh_ ->updateNormals ();
99- }
100-
101- // Apply skinning to get the posed mesh
102- applySSD (
103- cast<T>(character_.inverseBindPose ),
104- *this ->character_ .skinWeights ,
105- *this ->restMesh_ ,
106- state,
107- *this ->posedMesh_ );
108- }
109-
11080template <typename T>
11181double VertexVertexDistanceErrorFunctionT<T>::getGradient(
11282 const ModelParametersT<T>& modelParameters,
11383 const SkeletonStateT<T>& state,
114- const MeshStateT<T>& /* meshState */ ,
84+ const MeshStateT<T>& meshState,
11585 Eigen::Ref<Eigen::VectorX<T>> gradient) {
11686 MT_PROFILE_FUNCTION ();
11787
118- updateMeshes (modelParameters, state);
88+ MT_CHECK (
89+ meshState.posedMesh_ , " MeshState must have posed mesh for VertexVertexDistanceErrorFunction" );
11990
12091 double error = 0.0 ;
12192
12293 for (const auto & constraint : constraints_) {
123- error += calculateGradient (modelParameters, state, constraint, gradient);
94+ error += calculateGradient (modelParameters, state, meshState, constraint, gradient);
12495 }
12596
12697 return error * this ->weight_ ;
@@ -130,7 +101,7 @@ template <typename T>
130101double VertexVertexDistanceErrorFunctionT<T>::getJacobian(
131102 const ModelParametersT<T>& modelParameters,
132103 const SkeletonStateT<T>& state,
133- const MeshStateT<T>& /* meshState */ ,
104+ const MeshStateT<T>& meshState,
134105 Eigen::Ref<Eigen::MatrixX<T>> jacobian,
135106 Eigen::Ref<Eigen::VectorX<T>> residual,
136107 int & usedRows) {
@@ -141,7 +112,7 @@ double VertexVertexDistanceErrorFunctionT<T>::getJacobian(
141112 MT_CHECK (jacobian.rows () >= static_cast <Eigen::Index>(constraints_.size ()));
142113 MT_CHECK (residual.rows () >= static_cast <Eigen::Index>(constraints_.size ()));
143114
144- updateMeshes (modelParameters, state );
115+ MT_CHECK_NOTNULL (meshState. posedMesh_ );
145116
146117 double error = 0.0 ;
147118
@@ -150,6 +121,7 @@ double VertexVertexDistanceErrorFunctionT<T>::getJacobian(
150121 error += calculateJacobian (
151122 modelParameters,
152123 state,
124+ meshState,
153125 constraints_[i],
154126 jacobian.block (i, 0 , 1 , modelParameters.size ()),
155127 residualValue);
@@ -169,13 +141,14 @@ template <typename T>
169141double VertexVertexDistanceErrorFunctionT<T>::calculateJacobian(
170142 const ModelParametersT<T>& modelParameters,
171143 const SkeletonStateT<T>& state,
144+ const MeshStateT<T>& meshState,
172145 const VertexVertexDistanceConstraintT<T>& constraint,
173146 Eigen::Ref<Eigen::MatrixX<T>> jacobian,
174147 T& residual) const {
175148 MT_PROFILE_FUNCTION ();
176149
177- const auto & pos1 = posedMesh_->vertices [constraint.vertexIndex1 ];
178- const auto & pos2 = posedMesh_->vertices [constraint.vertexIndex2 ];
150+ const auto & pos1 = meshState. posedMesh_ ->vertices [constraint.vertexIndex1 ];
151+ const auto & pos2 = meshState. posedMesh_ ->vertices [constraint.vertexIndex2 ];
179152
180153 const Eigen::Vector3<T> diff = pos1 - pos2;
181154 const T actualDistance = diff.norm ();
@@ -197,11 +170,16 @@ double VertexVertexDistanceErrorFunctionT<T>::calculateJacobian(
197170
198171 // Calculate jacobian contribution from vertex1 (positive contribution)
199172 calculateVertexJacobian (
200- modelParameters, state, constraint.vertexIndex1 , wgt * distanceGradient, jacobian);
173+ modelParameters, state, meshState, constraint.vertexIndex1 , wgt * distanceGradient, jacobian);
201174
202175 // Calculate jacobian contribution from vertex2 (negative contribution)
203176 calculateVertexJacobian (
204- modelParameters, state, constraint.vertexIndex2 , -wgt * distanceGradient, jacobian);
177+ modelParameters,
178+ state,
179+ meshState,
180+ constraint.vertexIndex2 ,
181+ -wgt * distanceGradient,
182+ jacobian);
205183
206184 return wgt * wgt * distanceDiff * distanceDiff;
207185}
@@ -210,12 +188,14 @@ template <typename T>
210188void VertexVertexDistanceErrorFunctionT<T>::calculateVertexJacobian(
211189 const ModelParametersT<T>& /* modelParameters*/ ,
212190 const SkeletonStateT<T>& state,
191+ const MeshStateT<T>& meshState,
213192 int vertexIndex,
214193 const Eigen::Vector3<T>& jacobianDirection,
215194 Eigen::Ref<Eigen::MatrixX<T>> jacobian) const {
216195 MT_PROFILE_FUNCTION ();
217196
218- SkinningWeightIteratorT<T> skinningIter (this ->character_ , *this ->restMesh_ , state, vertexIndex);
197+ SkinningWeightIteratorT<T> skinningIter (
198+ this ->character_ , *meshState.restMesh_ , state, vertexIndex);
219199
220200 // Handle derivatives wrt joint parameters
221201 while (!skinningIter.finished ()) {
@@ -307,12 +287,13 @@ template <typename T>
307287double VertexVertexDistanceErrorFunctionT<T>::calculateGradient(
308288 const ModelParametersT<T>& modelParameters,
309289 const SkeletonStateT<T>& state,
290+ const MeshStateT<T>& meshState,
310291 const VertexVertexDistanceConstraintT<T>& constraint,
311292 Eigen::Ref<Eigen::VectorX<T>> gradient) const {
312293 MT_PROFILE_FUNCTION ();
313294
314- const auto & pos1 = posedMesh_->vertices [constraint.vertexIndex1 ];
315- const auto & pos2 = posedMesh_->vertices [constraint.vertexIndex2 ];
295+ const auto & pos1 = meshState. posedMesh_ ->vertices [constraint.vertexIndex1 ];
296+ const auto & pos2 = meshState. posedMesh_ ->vertices [constraint.vertexIndex2 ];
316297
317298 const Eigen::Vector3<T> diff = pos1 - pos2;
318299 const T actualDistance = diff.norm ();
@@ -330,11 +311,16 @@ double VertexVertexDistanceErrorFunctionT<T>::calculateGradient(
330311
331312 // Calculate gradient contribution from vertex1 (positive contribution)
332313 calculateVertexGradient (
333- modelParameters, state, constraint.vertexIndex1 , wgt * distanceGradient, gradient);
314+ modelParameters, state, meshState, constraint.vertexIndex1 , wgt * distanceGradient, gradient);
334315
335316 // Calculate gradient contribution from vertex2 (negative contribution)
336317 calculateVertexGradient (
337- modelParameters, state, constraint.vertexIndex2 , -wgt * distanceGradient, gradient);
318+ modelParameters,
319+ state,
320+ meshState,
321+ constraint.vertexIndex2 ,
322+ -wgt * distanceGradient,
323+ gradient);
338324
339325 return constraint.weight * distanceDiff * distanceDiff;
340326}
@@ -343,12 +329,14 @@ template <typename T>
343329void VertexVertexDistanceErrorFunctionT<T>::calculateVertexGradient(
344330 const ModelParametersT<T>& /* modelParameters*/ ,
345331 const SkeletonStateT<T>& state,
332+ const MeshStateT<T>& meshState,
346333 int vertexIndex,
347334 const Eigen::Vector3<T>& gradientDirection,
348335 Eigen::Ref<Eigen::VectorX<T>> gradient) const {
349336 MT_PROFILE_FUNCTION ();
350337
351- SkinningWeightIteratorT<T> skinningIter (this ->character_ , *this ->restMesh_ , state, vertexIndex);
338+ SkinningWeightIteratorT<T> skinningIter (
339+ this ->character_ , *meshState.restMesh_ , state, vertexIndex);
352340
353341 // Handle derivatives wrt joint parameters
354342 while (!skinningIter.finished ()) {
0 commit comments