00001
00002 #include "SFVec3fCellConstrained.h"
00003 #include "assertions.h"
00004 #include "ConstrainedVertex.h"
00005
00006
00007
00008 namespace animal
00009 {
00010 namespace octree
00011 {
00012
00018 Vec3d getNewParametersInCell( Vec3d vParams, Vec3d originalParams, unsigned int diffDepth )
00019 {
00020 FloatingPointType scale = 1.0;
00021 if( diffDepth != 0 )
00022 {
00023 scale /= 2<<(diffDepth-1);
00024 }
00025 return vParams + originalParams*scale;
00026 }
00027
00032 Vec3d getParametersInFrame( Vec3d params, unsigned short vId )
00033 {
00034 return Vec3d( LINEARFACTORALPHA(vId,params[0]), LINEARFACTORBETA(vId,params[1]), LINEARFACTORGAMMA(vId,params[2]) );
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044 SFVec3fCellConstrained::SFVec3fCellConstrained( X3DTK::SFVec3f *q, Cell* cell, int vertexID, X3DTK::SFVec3f normal ) :
00045 _vec(q), _cell(cell), _vertexID(vertexID)
00046 {
00047 computeParameters();
00048
00049 _normal = Vec3d( normal[0], normal[1], normal[2] );
00050
00051 _alphaNormal = _alpha + normal[0] / 100.0;
00052 _betaNormal = _beta + normal[1] / 100.0;
00053 _gammaNormal = _gamma + normal[2] / 100.0;
00054
00055 for( unsigned short i=0 ; i<8 ; ++i )
00056 {
00057
00058 Vec3d w = getParameters(i);
00059 setRelativeWeight( _cell->vertex(i), computeWeight( w, LINEAR ) );
00060 setRelativePosition( _cell->vertex(i), w );
00061 }
00062 }
00063
00064 SFVec3fCellConstrained::SFVec3fCellConstrained( X3DTK::SFVec3f *q, Cell* cell, Vec3d params, int vertexID, Vec3d normal ) :
00065 _vec(q), _cell(cell), _normal(normal), _vertexID(vertexID)
00066 {
00067 _alpha = params[0];
00068 _beta = params[1];
00069 _gamma = params[2];
00070
00071 _alphaNormal = _alpha + normal[0] / 100.0;
00072 _betaNormal = _beta + normal[1] / 100.0;
00073 _gammaNormal = _gamma + normal[2] / 100.0;
00074 }
00075
00076 SFVec3fCellConstrained::~SFVec3fCellConstrained( )
00077 {
00078 }
00079
00080 void SFVec3fCellConstrained::setParams( const Vec3d params )
00081 {
00082 _alpha = params[0];
00083 _beta= params[1];
00084 _gamma = params[2];
00085 }
00086
00087 FloatingPointType SFVec3fCellConstrained::computeWeight( Vec3d w, int method )
00088 {
00089 switch( method )
00090 {
00091 case LINEAR:
00092 return (1.0-w[0]) * (1.0-w[1]) * (1.0-w[2]);
00093 case LOCAL_SKINNING:
00094 return hf.compute(w[0]) * hf.compute(w[1]) * hf.compute(w[2]);
00095 default:
00096 std::cerr << "SFVec3fCellConstrained::computeWeight() : Unknown method\n";
00097 return 0.0;
00098 }
00099 }
00100
00101
00102 void SFVec3fCellConstrained::updatePosition( int method )
00103 {
00104 Vec3d v = computePosition(method);
00105
00106 _vec->x = v[0];
00107 _vec->y = v[1];
00108 _vec->z = v[2];
00109 }
00110
00111
00112
00113 void SFVec3fCellConstrained::computeParameters()
00114 {
00115
00116 Vec3d q(_vec->x,_vec->y,_vec->z);
00117 Vec3d v = q - _cell->vertex(0)->getPosition();
00118
00119 Vec3d va = _cell->vertex(1)->getPosition() - _cell->vertex(0)->getPosition();
00120 Vec3d vb = _cell->vertex(2)->getPosition() - _cell->vertex(0)->getPosition();
00121 Vec3d vc = _cell->vertex(4)->getPosition() - _cell->vertex(0)->getPosition();
00122
00123 _alpha = (v*va) / (va.norm()*va.norm());
00124 _beta = (v*vb) / (vb.norm()*vb.norm());
00125 _gamma = (v*vc) / (vc.norm()*vc.norm());
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
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 Vec3d SFVec3fCellConstrained::computePosition( int method ) const
00247 {
00248 Vec3d vRes;
00249
00250
00251
00252 switch( method )
00253 {
00254 case LINEAR :
00255 {
00256 vRes =
00257 (1.0-_gamma)*(
00258 (1.0-_beta)*( (1-_alpha)*_cell->vertex(0)->getPosition() + _alpha*_cell->vertex(1)->getPosition() )
00259 +
00260 _beta *( (1-_alpha)*_cell->vertex(2)->getPosition() + _alpha*_cell->vertex(3)->getPosition() ) )
00261 +
00262 _gamma*(
00263 (1.0-_beta)*( (1-_alpha)*_cell->vertex(4)->getPosition() + _alpha*_cell->vertex(5)->getPosition() )
00264 +
00265 _beta *( (1-_alpha)*_cell->vertex(6)->getPosition() + _alpha*_cell->vertex(7)->getPosition() )
00266 );
00267
00268 return vRes;
00269 }
00270
00271 case LOCAL_SKINNING:
00272 {
00273
00274 CellInfluenceData & cid = _cell->getData()._influence;
00275
00276 FloatingPointType wSum = 0.0;
00277 FloatingPointType w;
00278 for( unsigned int i=0 ; i<cid.vertices.size() ; ++i )
00279 {
00280
00281 w = getRelativeWeight( cid.vertices[i] );
00282 Frame &f = cid.vertices[i]->getFrame();
00283 Vec3d relPos = getRelativePosition(cid.vertices[i]);
00284
00285 Vec3d initSize(1.0,1.0,1.0);
00286
00287
00288
00289
00290
00291 vRes += w * f.computePosition( relPos, initSize );
00292
00293 wSum += w;
00294 }
00295
00296 vRes /= wSum;
00297
00298 return vRes;
00299 }
00300
00301 default:
00302 {
00303 std::cerr << "SFVec3fCellConstrained::computePosition() : unknown method\n";
00304 return Vec3d(0.0,0.0,0.0);
00305 }
00306 }
00307 }
00308
00309
00310 std::vector<Vec3d> SFVec3fCellConstrained::computeDerivative( ) const
00311 {
00312 std::vector<Vec3d> res(3);
00313
00314 static const FloatingPointType d = 10e-5;
00315
00316 SFVec3fCellConstrained tmpVec = *this;
00317 Vec3d posT, posB;
00318
00319
00320 tmpVec.setParams( this->getLocalParams() + Vec3d(d,0.0,0.0) );
00321 tmpVec.updateSkinningInformations( _cell->getData()._influence );
00322 posT = tmpVec.computePosition( LOCAL_SKINNING );
00323 tmpVec.setParams( this->getLocalParams() + Vec3d(-d,0.0,0.0) );
00324 tmpVec.updateSkinningInformations( _cell->getData()._influence );
00325 posB = tmpVec.computePosition( LOCAL_SKINNING );
00326 res[0] = (posT-posB)/(2.0*d);
00327
00328 tmpVec.setParams( this->getLocalParams() + Vec3d(0.0,+d,0.0) );
00329 tmpVec.updateSkinningInformations( _cell->getData()._influence );
00330 posT = tmpVec.computePosition( LOCAL_SKINNING );
00331 tmpVec.setParams( this->getLocalParams() + Vec3d(0.0,-d,0.0) );
00332 tmpVec.updateSkinningInformations( _cell->getData()._influence );
00333 posB = tmpVec.computePosition( LOCAL_SKINNING );
00334 res[1] = (posT-posB)/(2.0*d);
00335
00336 tmpVec.setParams( this->getLocalParams() + Vec3d(0.0,0.0,+d) );
00337 tmpVec.updateSkinningInformations( _cell->getData()._influence );
00338 posT = tmpVec.computePosition( LOCAL_SKINNING );
00339 tmpVec.setParams( this->getLocalParams() + Vec3d(0.0,0.0,-d) );
00340 tmpVec.updateSkinningInformations( _cell->getData()._influence );
00341 posB = tmpVec.computePosition( LOCAL_SKINNING );
00342 res[2] = (posT-posB)/(2.0*d);
00343
00344 return res;
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 }
00447
00448
00449 Vec3d SFVec3fCellConstrained::getParameters( unsigned short vId ) const
00450 {
00451 Require( vId < 8 );
00452 return Vec3d(LINEARFACTORALPHA(vId,_alpha),LINEARFACTORBETA(vId,_beta),LINEARFACTORGAMMA(vId,_gamma));
00453 }
00454
00455
00456 void SFVec3fCellConstrained::updateSkinningInformations( CellInfluenceData & influence )
00457 {
00458 this->clearRelativePositions( );
00459 this->clearRelativeWeights( );
00460
00461
00462
00463 for( unsigned short vId=0 ; vId < influence.vertices.size() ; ++vId )
00464 {
00465
00466
00467
00468
00469
00470
00471
00472 Vec3d params = translateParameters( this->getCell(), this->getLocalParams(), (Cell*)influence.parents[vId], influence.verticesId[vId] );
00473 this->setRelativePosition( influence.vertices[vId], params );
00474
00475 Vec3d paramW;
00476 for( unsigned short i=0 ; i<8 ; ++i )
00477 {
00478 FloatingPointType w = computeWeight( getParameters(i), LINEAR );
00479 paramW += w * influence.influenceMaps[vId][_cell->vertex(i)];
00480 }
00481 FloatingPointType w = computeWeight( paramW, LOCAL_SKINNING );
00482 this->setRelativeWeight( influence.vertices[vId], w );
00483 }
00484 }
00485
00486
00487
00488
00489
00490
00491 void SFVec3fCellConstrained::globalLinearUpdatePositions( Cell *cStart )
00492 {
00493 for( Cell::vertex_width_iterator it(cStart) ; !it.empty() ; )
00494 {
00495 ConstrainedVertex* v = ++it;
00496
00497 if( v->isFree() )
00498 {
00499 Vec3d delta = v->getDelta();
00500 X3DTK::SFVec3f sfDelta(delta[0],delta[1],delta[2]);
00501
00502 for( unsigned int i=0 ; i<v->nConnectedCells() ; ++i )
00503 {
00504 Cell *cell = v->connectedCell(i);
00505
00506 if( cell->getData()._depth == v->getDepth() )
00507 {
00508 unsigned int vId;
00509 for( vId=0 ; vId<8 ; ++vId )
00510 {
00511 if( cell->vertex(vId) == v )
00512 {
00513 break;
00514 }
00515 }
00516
00517 OctreeDataPoints *points = &(cell->getData()._points);
00518 for( OctreeDataPoints::iterator it = points->begin() ; it != points->end() ; ++it )
00519 {
00520 X3DTK::SFVec3f *vec = (*it)->getSFVec3f();
00521 FloatingPointType weight = hf.compute(LINEARFACTORALPHA(vId,(*it)->getAlpha())) * hf.compute(LINEARFACTORBETA(vId,(*it)->getBeta())) * hf.compute(LINEARFACTORGAMMA(vId,(*it)->getGamma()));
00522 weight /= ((FloatingPointType) v->getDepth() + 1.0);
00523 *vec += weight*sfDelta;
00524 }
00525 }
00526 }
00527 }
00528
00529 v->setDelta( Vec3d(0,0,0) );
00530 }
00531 }
00532
00533 Vec3d SFVec3fCellConstrained::getInitNormalParameters( unsigned short vId ) const
00534 {
00535 Require( vId < 8 );
00536 return Vec3d(LINEARFACTORALPHA(vId,_alphaNormal),LINEARFACTORBETA(vId,_betaNormal),LINEARFACTORGAMMA(vId,_gammaNormal));
00537 }
00538
00539
00547 Vec3d SFVec3fCellConstrained::translateParameters( Cell *cStart, Vec3d params, Cell *cDest, unsigned short vId )
00548 {
00549
00550
00551 Vec3d result = params;
00552
00553 Cell *cell = cStart;
00554
00555 while( cell != cDest )
00556 {
00557 if( (cell->fatherPos()%2) == 0 )
00558 {
00559 result[0] /= 2.0;
00560 }
00561 else
00562 {
00563 result[0] = (result[0]+1.0)/2.0;
00564 }
00565 if( (cell->fatherPos()%4) <= 1 )
00566 {
00567 result[1] /= 2.0;
00568 }
00569 else
00570 {
00571 result[1] = (result[1]+1.0)/2.0;
00572 }
00573 if( cell->fatherPos() <= 3 )
00574 {
00575 result[2] /= 2.0;
00576 }
00577 else
00578 {
00579 result[2] = (result[2]+1.0)/2.0;
00580 }
00581
00582 cell = cell->father();
00583 }
00584
00585
00586 result = Vec3d( LINEARFACTORALPHA(vId,result[0]), LINEARFACTORBETA(vId,result[1]), LINEARFACTORGAMMA(vId,result[2]) );
00587 if( (vId%2) == 1 )
00588 {
00589 result[0] *= -1;
00590 }
00591 if( (vId%4) >= 2 )
00592 {
00593 result[1] *= -1;
00594 }
00595 if( vId >= 4 )
00596 {
00597 result[2] *= -1;
00598 }
00599
00600 return result;
00601 }
00602
00603
00604 }
00605 }
00606