Changeset 516
- Timestamp:
- 02/22/08 17:30:39 (11 months ago)
- Files:
-
- branches/morph-targets/libx42make/helpers.h (modified) (2 diffs)
- branches/morph-targets/libx42make/include/x42make-modelbuilder.h (modified) (8 diffs)
- branches/morph-targets/libx42make/modelbuilder-animation.cpp (modified) (4 diffs)
- branches/morph-targets/libx42make/modelbuilder-enumerators.cpp (modified) (2 diffs)
- branches/morph-targets/libx42make/modelbuilder-geometry.cpp (modified) (2 diffs)
- branches/morph-targets/libx42make/modelbuilder-influences.cpp (modified) (1 diff)
- branches/morph-targets/libx42make/modelbuilder-skeleton.cpp (modified) (1 diff)
- branches/morph-targets/libx42pp/include/x42math-angle.h (modified) (2 diffs)
- branches/morph-targets/x42view.net/Gui/DXPanel.Designer.cs (modified) (2 diffs)
- branches/morph-targets/x42view.net/Gui/MoveHelper.cs (modified) (1 diff)
- branches/morph-targets/x42view.net/Gui/TimeControl.Designer.cs (modified) (2 diffs)
- branches/morph-targets/x42view.net/Gui/TimeSlider.cs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/morph-targets/libx42make/helpers.h
r515 r516 107 107 struct equal 108 108 { 109 bool operator() ( const T &a, const T &b ) 109 bool operator() ( const T &a, const T &b ) const 110 110 { 111 111 return a == b; … … 116 116 } 117 117 118 template< typename T, typename Cmp > 119 void ordered_insert( std::vector< T > &v, 120 const T &val, Cmp cmp, bool allow_duplicates = true ) 121 { 122 std::vector< T >::iterator pos = 123 std::upper_bound( v.begin(), v.end(), val, cmp ); 124 125 if( !allow_duplicates ) 126 { 127 if( pos > v.begin() ) 128 { 129 const T &vp = pos[-1]; 130 131 if( !cmp( vp, val ) && !cmp( val, vp ) ) 132 //neither is less, they are "equal" 133 return; 134 } 135 } 136 137 v.insert( pos, val ); 138 } 139 140 template< typename T > 141 void ordered_insert( std::vector< T > &v, 142 const T &val, bool allow_duplicates = true ) 143 { 144 ordered_insert( v, val, std::less< T >(), allow_duplicates ); 145 } 146 147 template< typename T > 148 std::vector< uint > gather_frame_numbers( const std::vector< anim_track_elem< T > > &track ) 149 { 150 std::vector< uint > ret( track.size() ); 151 152 for( size_t i = 0; i < track.size(); i++ ) 153 ret[i] = track[i].frame; 154 155 return ret; 156 } 157 118 158 }; 119 159 }; branches/morph-targets/libx42make/include/x42make-modelbuilder.h
r515 r516 120 120 uint frame; 121 121 T value; 122 123 anim_track_elem() 124 { 125 } 126 anim_track_elem( uint frame, const T &value ) 127 : frame( frame ), value( value ) 128 { 129 } 122 130 }; 123 131 … … 175 183 void require_world(); 176 184 185 void offset_world( const ::x42::math::affine &offset ); 186 void offset_local( const ::x42::math::affine &offset ); 187 188 void resample_tracks( const std::vector< uint > &frames ); 189 177 190 void clean_tracks(); 191 192 void make_scale_uniform(); 178 193 179 194 private: … … 209 224 animation_tolerances tight_tolerances; 210 225 211 bool static_bone_hint; 226 bool no_remove; //set to true to keep optimizations from deleting this bone 227 bool static_bone_hint; //set to true if it's known that this bone does not animate *relative to its parent* 212 228 213 229 bone_ptr parent() const { return _parent; } … … 233 249 loose_tolerances( animation_tolerances::inherit_defaults() ), 234 250 tight_tolerances( animation_tolerances::inherit_defaults() ), 235 static_bone_hint( false ) 251 static_bone_hint( false ), no_remove( false ) 236 252 { 237 253 anim_tracks.owner = this; … … 315 331 influence_ptr influence() const { return _influence; } 316 332 float weight() const { return _weight; } 333 334 bool is_empty() const { return !_influence || _weight == 0; } 317 335 318 336 private: … … 424 442 std::string surface_name; 425 443 std::string material_name; 426 geometry group_geometry; 444 geometry geometry; 445 446 std::vector< influence_ptr > get_influences() const; 427 447 428 448 private: … … 499 519 void begin_skeleton_update(); 500 520 void end_skeleton_update(); 521 522 void apply_root_scale( const ::x42::math::vec3 &pos_ofs, const ::x42::math::quat &rot_ofs, 523 const ::x42::math::vec3 &inner_scale_ofs, const ::x42::math::vec3 &outer_scale_ofs ); 501 524 502 525 //unbinds all vertices from influence … … 508 531 //unbinds all vertices from old_influence and binds them to new_influence with the same weight, then removes old_influence 509 532 void rebind_and_remove_influence( const influence_ptr &old_influence, const influence_ptr &new_influence ); 533 //rebinds vertices such that only one influence out of each set of equivalent influences is in use 534 void rebind_duplicate_influences(); 510 535 511 536 void unbind_weak_influences( float min_weight, bool renormalize_weights = true ); branches/morph-targets/libx42make/modelbuilder-animation.cpp
r515 r516 57 57 } 58 58 59 template< typename T > 60 T sample_track( const std::vector< anim_track_elem< T > > &track, float frame ) 61 { 62 if( !track.size() ) 63 return T(); 64 65 if( track[0].frame > frame ) 66 return track[0].value; 67 68 for( uint i = 1; i < track.size(); i++ ) 69 { 70 if( track[i].frame >= frame ) 71 { 72 const anim_track_elem< T > &s = track[i - 1]; 73 const anim_track_elem< T > &e = track[i]; 74 75 float t = (float)(frame - s.frame) / (float)(e.frame - s.frame); 76 return interp_elem( s.value, e.value, t ); 77 } 78 } 79 80 return track[track.size() - 1].value; 81 } 82 83 template< typename T > 84 std::vector< anim_track_elem< T > > resample_track( 85 const std::vector< anim_track_elem< T > > &track, 86 const std::vector< uint > &frames ) 87 { 88 std::vector< anim_track_elem< T > > ret( frames.size() ); 89 90 for( size_t i = 0; i < ret.size(); i++ ) 91 { 92 ret[i].frame = frames[i]; 93 ret[i].value = sample_track( track, (float)frames[i] ); 94 } 95 96 return ret; 97 } 98 59 99 inline float compute_delta( const vec3 &s, const vec3 &e, float t, const vec3 &m ) 60 100 { … … 343 383 } 344 384 385 void animation_tracks::offset_world( const affine &offset ) 386 { 387 require_world(); 388 389 for( size_t i = 0; i < world_matrices.size(); i++ ) 390 world_matrices[i].value = offset * world_matrices[i].value; 391 392 local_matrices.clear(); 393 position.clear(); 394 rotation.clear(); 395 scale.clear(); 396 } 397 398 void animation_tracks::offset_local( const affine &offset ) 399 { 400 require_local(); 401 402 for( size_t i = 0; i < local_matrices.size(); i++ ) 403 local_matrices[i].value = offset * local_matrices[i].value; 404 405 world_matrices.clear(); 406 position.clear(); 407 rotation.clear(); 408 scale.clear(); 409 } 410 411 void animation_tracks::resample_tracks( const std::vector< uint > &frames ) 412 { 413 require_tracks(); 414 415 std::vector< vec3_track_elem > new_pos = resample_track( position, frames ); 416 std::vector< quat_track_elem > new_rot = resample_track( rotation, frames ); 417 std::vector< vec3_track_elem > new_scale = resample_track( scale, frames ); 418 419 std::swap( position, new_pos ); 420 std::swap( rotation, new_rot ); 421 std::swap( scale, new_scale ); 422 } 423 345 424 void animation_tracks::clean_tracks() 346 425 { … … 376 455 } 377 456 457 void animation_tracks::make_scale_uniform() 458 { 459 require_tracks(); 460 461 for( size_t i = 0; i < scale.size(); i++ ) 462 { 463 vec3 &v = scale[i].value; 464 465 float mid = (v.x + v.y + v.z) / 3.0F; 466 467 v = vec3c( mid ); 468 } 469 } 470 378 471 /* 379 472 class model_builder … … 401 494 } 402 495 496 void model_builder::apply_root_scale( const vec3 &pos_ofs, const quat &rot_ofs, 497 const vec3 &inner_scale_ofs, const vec3 &outer_scale_ofs ) 498 { 499 if( !_frame_count ) 500 throw error( "Frame range not initialized." ); 501 502 std::vector< uint > frames; 503 if( bones.size() ) 504 { 505 const animation_tracks &anim_trks = bones[0]->anim_tracks; 506 507 if( anim_trks.world_matrices.size() ) 508 frames = gather_frame_numbers( anim_trks.world_matrices ); 509 else if( anim_trks.local_matrices.size() ) 510 frames = gather_frame_numbers( anim_trks.local_matrices ); 511 else if( anim_trks.position.size() ) 512 frames = gather_frame_numbers( anim_trks.position ); 513 } 514 515 if( !frames.size() ) 516 { 517 frames.resize( _frame_count ); 518 for( size_t i = 0; i < _frame_count; i++ ) 519 { 520 frames[i] = (uint)i; 521 } 522 } 523 524 begin_bone_update(); 525 526 bone_ptr root = create_bone( "root-offset" ); 527 528 root->_anim_group = 0; 529 root->flags = bone_flags::none; 530 root->static_bone_hint = true; 531 532 root->anim_tracks.position.push_back( 533 vec3_track_elem( _frame_count - 1, pos_ofs ) ); 534 root->anim_tracks.rotation.push_back( 535 quat_track_elem( _frame_count - 1, rot_ofs ) ); 536 root->anim_tracks.scale.push_back( 537 vec3_track_elem( _frame_count - 1, inner_scale_ofs * outer_scale_ofs ) ); 538 539 root->anim_tracks.resample_tracks( frames ); 540 541 root->anim_tracks.require_world(); 542 const affine &offset = root->anim_tracks.world_matrices[0].value; 543 544 for( size_t i = 0; i < bones.size(); i++ ) 545 { 546 bone_ptr b = bones[i]; 547 548 if( !b->_parent ) 549 b->_parent = root; 550 551 if( b->anim_tracks.world_matrices.size() ) 552 b->anim_tracks.offset_world( offset ); 553 } 554 555 for( size_t i = 0; i < influences.size(); i++ ) 556 { 557 influence_ptr inf = influences[i]; 558 559 if( !inf->_bone ) 560 inf->_bone = root; 561 } 562 563 affine inv_scale = 564 { { 565 { 1.0F / inner_scale_ofs.x, 0, 0 }, 566 { 0, 1.0F / inner_scale_ofs.y, 0 }, 567 { 0, 0, 1.0F / inner_scale_ofs.z }, 568 { 0, 0, 0 } 569 } }; 570 571 for( size_t i = 0; i < tags.size(); i++ ) 572 { 573 tag_ptr tag = tags[i]; 574 575 if( !tag->_bone ) 576 tag->_bone = root; 577 578 tag->matrix = inv_scale * tag->matrix; 579 } 580 581 root->anim_tracks.require_world(); 582 583 end_bone_update(); 584 } 585 403 586 }; 404 587 }; branches/morph-targets/libx42make/modelbuilder-enumerators.cpp
r513 r516 150 150 for( ; ; ) 151 151 { 152 if( (size_t)++cur_idx < cur_grp->g roup_geometry.vertex_count() )152 if( (size_t)++cur_idx < cur_grp->geometry.vertex_count() ) 153 153 return true; 154 154 … … 174 174 throw error(); 175 175 176 return cur_grp->g roup_geometry;176 return cur_grp->geometry; 177 177 } 178 178 branches/morph-targets/libx42make/modelbuilder-geometry.cpp
r514 r516 372 372 373 373 /* 374 class group 375 */ 376 377 std::vector< influence_ptr > group::get_influences() const 378 { 379 std::vector< influence_ptr > ret; 380 381 for( size_t i = 0; i < geometry.weights.size(); i++ ) 382 { 383 const vertex_weights &weights = geometry.weights[i]; 384 385 for( size_t j = 0; j < vertex_weights::max_weights; j++ ) 386 { 387 const vertex_weight &wt = weights[i]; 388 389 if( !wt.is_empty() ) 390 ordered_insert( ret, wt.influence(), false ); 391 } 392 } 393 394 struct influence_cmp 395 { 396 bool operator() ( const influence_ptr &a, const influence_ptr &b ) const 397 { 398 return a->index() < b->index(); 399 } 400 }; 401 402 std::sort( ret.begin(), ret.end(), influence_cmp() ); 403 404 return ret; 405 } 406 407 /* 374 408 class model_builder 375 409 */ … … 379 413 for( group_enumerator iter( *this ); iter.next(); ) 380 414 { 381 iter.current()->g roup_geometry.optimize( opt_type );415 iter.current()->geometry.optimize( opt_type ); 382 416 } 383 417 } branches/morph-targets/libx42make/modelbuilder-influences.cpp
r513 r516 150 150 } 151 151 152 void model_builder::rebind_duplicate_influences() 153 { 154 std::vector< size_t > use_counts = count_influence_uses(); 155 156 for( size_t i = influences.size(); i--; ) 157 { 158 if( !use_counts[i] ) 159 //affects nothing, don't care 160 continue; 161 162 influence_ptr ii = influences[i]; 163 164 for( size_t j = i; j--; ) 165 { 166 if( !use_counts[j] ) 167 //affects nothing, don't care 168 continue; 169 170 influence_ptr ij = influences[j]; 171 172 if( ii->_bone != ij->_bone ) 173 //not equal, next 174 continue; 175 176 if( !equal( ii->matrix, ij->matrix, 1e-2F ) ) 177 //not equal enough, next 178 continue; 179 180 /* 181 Favor keeping the bigger one. 182 183 ToDo: fix this code so it correctly handles cases 184 where more than two influences are equivalent. 185 */ 186 187 if( use_counts[i] > use_counts[j] ) 188 { 189 rebind_influence( ij, ii ); 190 191 use_counts[i] += use_counts[j]; 192 use_counts[j] = 0; 193 } 194 else 195 { 196 rebind_influence( ii, ij ); 197 198 use_counts[j] += use_counts[i]; 199 use_counts[i] = 0; 200 201 break; //stop comparing to this one 202 } 203 } 204 } 205 } 206 152 207 void model_builder::erase_influence( const influence_ptr &influence ) 153 208 { branches/morph-targets/libx42make/modelbuilder-skeleton.cpp
r513 r516 138 138 ret->_anim_group = parent ? parent->_anim_group : 0; 139 139 140 sort_bones(); 141 140 142 return ret; 141 143 } branches/morph-targets/libx42pp/include/x42math-angle.h
r303 r516 29 29 */ 30 30 31 namespace x42 32 { 33 namespace math 34 { 35 31 36 struct angle 32 37 { … … 48 53 inline angle degs( float deg_val ) { angle ret = { deg_val * (3.14159265358979323846F / 180.0F) }; return ret; } 49 54 55 }; 56 }; 57 50 58 #endif branches/morph-targets/x42view.net/Gui/DXPanel.Designer.cs
r402 r516 51 51 private void InitializeComponent() 52 52 { 53 this.helper = new x42view.Gui l.MoveHelper();53 this.helper = new x42view.Gui.MoveHelper(); 54 54 this.SuspendLayout(); 55 55 // … … 64 64 #endregion 65 65 66 private x42view.Gui l.MoveHelper helper;66 private x42view.Gui.MoveHelper helper; 67 67 } 68 68 } branches/morph-targets/x42view.net/Gui/MoveHelper.cs
r402 r516 26 26 using System.Windows.Forms; 27 27 28 namespace x42view.Gui l28 namespace x42view.Gui 29 29 { 30 30 branches/morph-targets/x42view.net/Gui/TimeControl.Designer.cs
r479 r516 48 48 this.tips = new System.Windows.Forms.ToolTip( this.components ); 49 49 this.nudCurrTime = new System.Windows.Forms.NumericUpDown(); 50 this.time = new x42view.Gui l.TimeSlider();50 this.time = new x42view.Gui.TimeSlider(); 51 51 this.groupBox1 = new System.Windows.Forms.GroupBox(); 52 52 this.nudFrameRate = new System.Windows.Forms.NumericUpDown(); … … 223 223 #endregion 224 224 225 private x42view.Gui l.TimeSlider time;225 private x42view.Gui.TimeSlider time; 226 226 private System.Windows.Forms.Timer animTime; 227 227 private System.Windows.Forms.Button btnPlay; branches/morph-targets/x42view.net/Gui/TimeSlider.cs
r483 r516 26 26 using System.Windows.Forms; 27 27 28 namespace x42view.Gui l28 namespace x42view.Gui 29 29 { 30 30
