Documentation


DirectManipulation.cpp

Go to the documentation of this file.
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 //      std::cerr << "Weight[" << i << " is " << weights[i] << "and res = " << result[i] << "\n";
00035     }
00036     
00037     return result;  
00038     /*  
00039     std::cerr << "DM: deltaQ " << deltaQ << "\n";
00040     
00041     unsigned int nControlPoint = weights.size();
00042     
00043     // Compute the matrix B with the weights
00044     HMat B( 3, 3*nControlPoint );
00045     for( unsigned int i=0 ; i<nControlPoint ; ++i )
00046     {
00047         B[0][i] = weights[i];
00048         B[1][nControlPoint+1 + i] = weights[i];
00049         B[2][2*nControlPoint+1 + i] = weights[i];
00050     }
00051     
00052     std::cerr << "DM : B is " << B << "\n";
00053     
00054     HMat B1( 3*nControlPoint, 3*nControlPoint );
00055     m_eq_AtB( B1, B, B );
00056     std::cerr << "DM : B1 is " << B1 << "\n";   
00057     
00058     HMat LU(3*nControlPoint,3*nControlPoint);
00059     m_eq_ludcmp( LU, B1 );
00060     std::cerr << "DM : LU is " << LU << "\n";
00061     
00062     HMat LU_1(3*nControlPoint,3*nControlPoint);
00063         HVec aux(3*nControlPoint);
00064         m_eq_luinv( LU_1, LU, aux );
00065     std::cerr << "DM : LU_1 is " << LU_1 << "\n";
00066         
00067     
00068     HMat B_1( 3*nControlPoint, nControlPoint );
00069     m_eq_ABt( B_1, LU_1, B );
00070     std::cerr << "DM : B_1 is " << B_1 << "\n";
00071     
00072     // Now we have B^{+} in B_1
00073     HMat dQ( 3, 1 );
00074     dQ[0][0] = deltaQ[0]; dQ[1][0] = deltaQ[1]; dQ[2][0] = deltaQ[2];
00075     
00076     HMat dP(3*nControlPoint,1);
00077     m_eq_AB( dP, B_1, dQ );
00078     
00079     // Now we have the movements of control points in dP
00080     // Fill the resulting vectors
00081     std::vector<Vec3d> result(nControlPoint);
00082     
00083     for( unsigned int i=0 ; i<nControlPoint ; ++i )
00084     {
00085         result[i][0] = dP[i][0];
00086         result[i][1] = dP[nControlPoint+1 + i][0];
00087         result[i][2] = dP[2*nControlPoint+1 + i][0];
00088         std::cerr << "DM: result[" << i << "] = " << result[i] << "\n";
00089     }
00090     
00091     return result;
00092     */
00093     
00094 /*  
00095     Require( weights.size() != 0 );
00096     
00097     std::cerr << "DM: deltaQ " << deltaQ << "\n";
00098     
00099     unsigned int nControlPoint = weights.size();
00100     
00101     // Compute the matrix B with the weights
00102     HMat B( 1, nControlPoint );
00103     for( unsigned int i=0 ; i<nControlPoint ; ++i )
00104     {
00105         B[0][i] = weights[i];
00106         //std::cerr << "DM: weight[" << i << "] = " << weights[i] << "\n";
00107     }
00108     
00109     //std::cerr << "DM : B is " << B << "\n";
00110     
00111     HMat B1( nControlPoint, nControlPoint );
00112     m_eq_AtB( B1, B, B );
00113     //std::cerr << "DM : B1 is " << B1 << "\n"; 
00114     
00115     HMat LU(nControlPoint,nControlPoint);
00116     m_eq_ludcmp( LU, B1 );
00117     //std::cerr << "DM : LU is " << LU << "\n";
00118     
00119     HMat LU_1(nControlPoint,nControlPoint);
00120     HVec aux(nControlPoint);
00121     m_eq_luinv( LU_1, LU, aux );
00122     //std::cerr << "DM : LU_1 is " << LU_1 << "\n";
00123         
00124     
00125     HMat B_1( nControlPoint, 1 );
00126     m_eq_ABt( B_1, LU_1, B );
00127     //std::cerr << "DM : B_1 is " << B_1 << "\n";
00128     
00129     // Now we have B^{+} in B_1
00130     HMat dQ( 1, 3 );
00131     dQ[0][0] = deltaQ[0]; dQ[0][1] = deltaQ[1]; dQ[0][2] = deltaQ[2];
00132     
00133     HMat dP(nControlPoint,3);
00134     m_eq_AB( dP, B_1, dQ );
00135     
00136     // Now we have the movements of control points in dP
00137     // Fill the resulting vectors
00138     std::vector<Vec3d> result(nControlPoint);
00139     
00140     for( unsigned int i=0 ; i<nControlPoint ; ++i )
00141     {
00142         result[i][0] = dP[i][0];
00143         result[i][1] = dP[i][1];
00144         result[i][2] = dP[i][2];
00145         //std::cerr << "DM: result[" << i << "] = " << result[i] << "\n";
00146     }
00147     
00148     return result;
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,          // the alpha/beta/gamma params
00162             std::vector<ConstrainedVertex*> framesVertices, // in data
00163             std::vector<ConstrainedVertex*> & verticesToMove,   // the vertices that must be moved
00164             std::vector<Vec3d> & deltaP             // associated delta
00165             )
00166 {
00167 //  std::cerr << "computeDirectManipulationSkinning\n";
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     // Create a table containing the unique indices for each constrained vertex
00185     //
00186     std::map<ConstrainedVertex*,unsigned int> indexMap;
00187     //
00188     // Create simulteanously a map for each vertex
00189     // of the FREE connected vertices (defining the frame's vectors)
00190     // Have a joint definition of their associated weight
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 //          std::cerr << "Treating vertex " << i << "/" << nVert << "\n";
00199             
00200             ConstrainedVertex *cv = framesVertices[i];
00201             
00202             // Add it itself and add the vertices for the parents
00203 //          indexMap[ cv ] = lastIndex++;
00204             // From \sum w_i Q_i = \sum w_i ( P_i + B_i )
00205             jacobianWeights[ cv ] += weights[i];
00206             
00207 //          std::cerr << "Adding1 " << weights[i] << " to cv " << *cv << " (" << jacobianWeights[ cv ] << ")\n";
00208             
00209 //          std::cerr << "\tPointer is " << cv << " and weight is " << jacobianWeights[ cv ] << " (have added " << weights[i] << ")\n";
00210             // From B_i = \alpha U_i + \beta V_i + \gamma W_i
00211             // where U_i = k_{u,0,i} U_{P_{0,i}} + k_{u,1,i} U_{P_{1,i}}  - ( k_{u,0,i} + k_{u,1,i} ) P_i 
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 //              std::cerr << "Adding2 " << weights[i] * relPos[i][dir] * k << " to cv " << *cv << " (" << jacobianWeights[ cv ] << ")\n";
00218                 
00219                 //
00220                 // Now find our free parents and add their weight
00221                 // First for the 0's component
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 //                              std::cerr << "Adding3 " << tmp._w << " to cv " << *tmp._vert << " (" << jacobianWeights[ tmp._vert ] << ")\n";
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 //  Vec3d Q;
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 //  std::cerr << "weight sum is " << tmp << " and original was : " << weightSum << "\n";
00281     
00282     //
00283     // now call the solver
00284     //
00285     deltaP = computeDirectManipulationResultPseudoInverse( freeWeights, deltaQ );
00286     
00287 //  Vec3d tmpQ;
00288 //  for( i=0 ; i<deltaP.size() ; ++i )
00289 //  {
00290 //      tmpQ += freeWeights[i]*deltaP[i];
00291 //  }
00292 //  std::cerr << "\ttmpQ is " << tmpQ << "\n";
00293 //  
00294 //  Vec3d oldQ;
00295 //  Vec3d newQ;
00296 //  for( i=0 ; i<deltaP.size() ; ++i )
00297 //  {
00298 //      oldQ += freeWeights[i] * verticesToMove[i]->getPosition();
00299 //      newQ += freeWeights[i] * (verticesToMove[i]->getPosition() + deltaP[i]);
00300 //  }
00301 //  std::cerr << "\tOldQ is " << oldQ << "\n";
00302 //  std::cerr << "\tNEWQ is " << newQ << "\n";
00303     
00304 //  std::cerr << "Res is " << Q << "\n";
00305 //  std::vector<Vec3d> computeDirectManipulationResultPseudoInverse( std::vector<FloatingPointType> weights, Vec3d deltaQ )
00306     
00307 //  Vec3d verif;
00308 //  for( unsigned int i=0 ; i<nVert ; ++i )
00309 //  {
00310 //      Vec3d pos = framesVertices[i]->getPosition();
00311 //      
00312 //      std::cerr << "Frame " << i << " : " << weights[i] << " relPos : " << relPos[i] << "\n";
00313 //      
00314 //      Vec3d vecs[3];
00315 //      for( unsigned int dir=0 ; dir<3 ; ++dir )
00316 //      {
00317 //          vecs[dir] = (framesVertices[i]->_connectedVertices[dir][0]->getPosition() - framesVertices[i]->getPosition()) * framesVertices[i]->_connectedVerticesFactors[dir][0];
00318 //          if( framesVertices[i]->_connectedVerticesFactors[dir][1] != 0 )
00319 //          {
00320 //              vecs[dir] += (framesVertices[i]->_connectedVertices[dir][1]->getPosition() - framesVertices[i]->getPosition()) * framesVertices[i]->_connectedVerticesFactors[dir][1];
00321 //          }
00322 //          pos += vecs[dir] * relPos[i][dir];
00323 //      }
00324 //      std::cerr << "position is : " << pos << "\n";
00325 //      
00326 //      verif += pos * weights[i];
00327 //  }
00328 //  std::cerr << "Final : " << verif << "\n";
00329 }
00330 
00331 void computeDirectManipulationSkinningFrames(
00332                     Vec3d deltaQ,
00333                     std::vector<FloatingPointType> weights,
00334                     std::vector<Vec3d> relPos,
00335                     std::vector<ConstrainedVertex*> framesVertices, // in data
00336                     std::vector< std::vector<Vec3d> > & deltaFrames  // results here
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 //      RHS -= weights[i] * framesVertices[i]->getPosition();
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, // in data
00367                     std::vector< Vec3d > & deltas  // results here
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, // in data
00387                     std::vector< Vec3d > & deltas  // results here
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 

Generated on Thu Dec 23 13:52:24 2004 by doxygen 1.3.6