00001
00002 #include "DirectManipulation.h"
00003 #include "assertions.h"
00004
00005 #include <map>
00006
00007 namespace animal
00008 {
00009 namespace octree
00010 {
00011
00016 std::vector<Vec3d> computeDirectManipulationResultPseudoInverse( std::vector<FloatingPointType> weights, Vec3d deltaQ )
00017 {
00018
00019 Require( weights.size() != 0 );
00020
00021 std::vector<Vec3d> result(weights.size());
00022
00023
00024 FloatingPointType sum = 0.0;
00025 for( unsigned int i=0 ; i<weights.size() ; ++i )
00026 {
00027 sum += weights[i]*weights[i];
00028 }
00029
00030
00031 for( unsigned int i=0 ; i<weights.size() ; ++i )
00032 {
00033 result[i] = deltaQ * weights[i] / sum;
00034
00035 }
00036
00037 return result;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 }
00151
00152
00153 typedef struct {
00154 ConstrainedVertex *_vert;
00155 FloatingPointType _w;
00156 } VertexWeight ;
00157
00158 void computeDirectManipulationSkinning(
00159 Vec3d deltaQ,
00160 std::vector<FloatingPointType> weights,
00161 std::vector<Vec3d> relPos,
00162 std::vector<ConstrainedVertex*> framesVertices,
00163 std::vector<ConstrainedVertex*> & verticesToMove,
00164 std::vector<Vec3d> & deltaP
00165 )
00166 {
00167
00168 const unsigned int nVert = weights.size();
00169
00170 Require( relPos.size() == nVert );
00171 Require( framesVertices.size() == nVert );
00172 Require( nVert != 0 );
00173
00174 verticesToMove.clear();
00175 deltaP.clear();
00176
00177 FloatingPointType weightSum = 0.0;
00178 for( std::vector<FloatingPointType>::iterator it=weights.begin() ; it != weights.end() ; ++it )
00179 {
00180 weightSum += *it;
00181 }
00182
00183
00184
00185
00186 std::map<ConstrainedVertex*,unsigned int> indexMap;
00187
00188
00189
00190
00191
00192 std::map<ConstrainedVertex*,FloatingPointType> jacobianWeights;
00193
00194 {
00195 unsigned int lastIndex = 0;
00196 for( unsigned int i=0 ; i<nVert ; ++i )
00197 {
00198
00199
00200 ConstrainedVertex *cv = framesVertices[i];
00201
00202
00203
00204
00205 jacobianWeights[ cv ] += weights[i];
00206
00207
00208
00209
00210
00211
00212 for( unsigned int dir=0 ; dir<3 ; ++dir )
00213 {
00214 FloatingPointType k = -(cv->_connectedVerticesFactors[dir][0]+cv->_connectedVerticesFactors[dir][1]);
00215 jacobianWeights[cv] += weights[i] * relPos[i][dir] * k;
00216
00217
00218
00219
00220
00221
00222
00223 for( unsigned int comp=0 ; comp<=1 ; comp++ )
00224 {
00225 if( cv->_connectedVerticesFactors[dir][comp] != 0.0 )
00226 {
00227 std::list<VertexWeight> parentsWeights;
00228
00229 VertexWeight tmp;
00230 tmp._vert = cv->_connectedVertices[dir][comp];
00231 tmp._w = cv->_connectedVerticesFactors[dir][comp] * relPos[i][dir] * weights[i];
00232
00233 parentsWeights.push_back( tmp );
00234 while( !parentsWeights.empty() )
00235 {
00236 tmp = parentsWeights.front();
00237 parentsWeights.pop_front();
00238 if( tmp._vert->isFree() )
00239 {
00240 jacobianWeights[tmp._vert] += tmp._w;
00241
00242 }
00243 else
00244 {
00245 unsigned int nP = tmp._vert->getGeoLink()->getNGeoParents();
00246 FloatingPointType weightP = tmp._w / (FloatingPointType)nP;
00247 for( unsigned int j=0 ; j<nP ; ++j )
00248 {
00249 VertexWeight tmp2;
00250 tmp2._vert = tmp._vert->getGeoLink()->getGeoParent( tmp._vert->getGeoLink()->getGeoParentId(j) );
00251 tmp2._w = weightP;
00252 parentsWeights.push_back( tmp2 );
00253 }
00254 }
00255 }
00256 }
00257 }
00258
00259 }
00260 }
00261 }
00262
00263
00264
00265 std::vector<FloatingPointType> freeWeights( jacobianWeights.size() );
00266 verticesToMove.resize( freeWeights.size() );
00267
00268 double tmp = 0.0;
00269 unsigned int i=0;
00270 for( std::map<ConstrainedVertex*,FloatingPointType>::iterator it = jacobianWeights.begin() ;
00271 it != jacobianWeights.end() ;
00272 ++it, ++i )
00273 {
00274 (*it).second /= weightSum;
00275 freeWeights[i] = (*it).second;
00276 verticesToMove[i] = (*it).first;
00277
00278 tmp += freeWeights[i];
00279 }
00280
00281
00282
00283
00284
00285 deltaP = computeDirectManipulationResultPseudoInverse( freeWeights, deltaQ );
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 }
00330
00331 void computeDirectManipulationSkinningFrames(
00332 Vec3d deltaQ,
00333 std::vector<FloatingPointType> weights,
00334 std::vector<Vec3d> relPos,
00335 std::vector<ConstrainedVertex*> framesVertices,
00336 std::vector< std::vector<Vec3d> > & deltaFrames
00337 )
00338 {
00339 deltaFrames.clear();
00340 deltaFrames.resize( framesVertices.size() );
00341
00342 std::vector<FloatingPointType> framesWeights;
00343 for( unsigned int i=0 ; i<framesVertices.size() ; ++i )
00344 {
00345
00346 framesWeights.push_back( weights[i] * relPos[i][0] );
00347 framesWeights.push_back( weights[i] * relPos[i][1] );
00348 framesWeights.push_back( weights[i] * relPos[i][2] );
00349 }
00350
00351 std::vector<Vec3d> deltaV;
00352 deltaV = computeDirectManipulationResultPseudoInverse( framesWeights, deltaQ );
00353
00354 for( unsigned int i=0 ; i<framesVertices.size() ; ++i )
00355 {
00356 deltaFrames[i].push_back( deltaV[i*3+0] );
00357 deltaFrames[i].push_back( deltaV[i*3+1] );
00358 deltaFrames[i].push_back( deltaV[i*3+2] );
00359 }
00360 }
00361
00362 void computeDirectManipulationSkinningVerticesAndFrames(
00363 Vec3d deltaQ,
00364 std::vector<FloatingPointType> weights,
00365 std::vector<Vec3d> relPos,
00366 std::vector<ConstrainedVertex*> framesVertices,
00367 std::vector< Vec3d > & deltas
00368 )
00369 {
00370 std::vector<FloatingPointType> myWeights;
00371 for( unsigned int i=0 ; i<weights.size() ; ++i )
00372 {
00373 myWeights.push_back( weights[i] );
00374 myWeights.push_back( weights[i] * relPos[i][0] );
00375 myWeights.push_back( weights[i] * relPos[i][1] );
00376 myWeights.push_back( weights[i] * relPos[i][2] );
00377 }
00378
00379 deltas = computeDirectManipulationResultPseudoInverse( myWeights, deltaQ );
00380 }
00381
00382 void computeDirectManipulationSkinningVertices(
00383 Vec3d deltaQ,
00384 std::vector<FloatingPointType> weights,
00385 std::vector<Vec3d> relPos,
00386 std::vector<ConstrainedVertex*> framesVertices,
00387 std::vector< Vec3d > & deltas
00388 )
00389 {
00390 std::vector<FloatingPointType> myWeights;
00391 for( unsigned int i=0 ; i<weights.size() ; ++i )
00392 {
00393 myWeights.push_back( weights[i] );
00394 }
00395
00396 deltas = computeDirectManipulationResultPseudoInverse( myWeights, deltaQ );
00397 }
00398
00399 }
00400 }
00401
00402