- Timestamp:
- 07/21/14 02:42:49 (11 years ago)
- Location:
- trunk/nv
- Files:
-
- 3 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/gfx/animation.hh
r285 r286 12 12 #include <nv/interface/stream.hh> 13 13 #include <nv/math.hh> 14 #include <nv/interface/vertex.hh> 14 #include <nv/interface/animation_key.hh> 15 #include <nv/interface/interpolation_raw.hh> 16 #include <nv/interface/interpolation_template.hh> 15 17 #include <nv/transform.hh> 16 18 #include <glm/gtc/matrix_transform.hpp> -
trunk/nv/interface/vertex.hh
r285 r286 32 32 }; 33 33 34 enum class animation_slot : uint835 {36 TIME = 0,37 POSITION = 1,38 ROTATION = 2,39 SCALE = 3,40 TFORM = 4,41 42 SLOT_MAX = 4,43 SLOT_MAX_STORE = 8,44 };45 46 34 namespace detail 47 35 { … … 213 201 }; 214 202 215 template < typename KEY, animation_slot SLOT >216 struct key_has_slot_impl217 {218 static bool const value = false;219 };220 221 template < typename KEY >222 struct key_has_slot_impl< KEY, animation_slot::TIME >223 {224 private:225 struct fallback { int time; };226 struct derived : KEY, fallback { };227 template<typename C, C> struct cht;228 template<typename C> static char (&test(cht<int fallback::*, &C::time>*))[1];229 template<typename C> static char (&test(...))[2];230 public:231 static bool const value = sizeof(test<derived>(0)) == 2;;232 };233 234 template < typename KEY >235 struct key_has_slot_impl< KEY, animation_slot::POSITION >236 {237 private:238 struct fallback { int position; };239 struct derived : KEY, fallback { };240 template<typename C, C> struct cht;241 template<typename C> static char (&test(cht<int fallback::*, &C::position>*))[1];242 template<typename C> static char (&test(...))[2];243 public:244 static bool const value = sizeof(test<derived>(0)) == 2;;245 };246 247 template < typename KEY >248 struct key_has_slot_impl< KEY, animation_slot::ROTATION >249 {250 private:251 struct fallback { int rotation; };252 struct derived : KEY, fallback { };253 template<typename C, C> struct cht;254 template<typename C> static char (&test(cht<int fallback::*, &C::rotation>*))[1];255 template<typename C> static char (&test(...))[2];256 public:257 static bool const value = sizeof(test<derived>(0)) == 2;;258 };259 260 template < typename KEY >261 struct key_has_slot_impl< KEY, animation_slot::SCALE >262 {263 private:264 struct fallback { int scale; };265 struct derived : KEY, fallback { };266 template<typename C, C> struct cht;267 template<typename C> static char (&test(cht<int fallback::*, &C::scale>*))[1];268 template<typename C> static char (&test(...))[2];269 public:270 static bool const value = sizeof(test<derived>(0)) == 2;;271 };272 273 template < typename KEY >274 struct key_has_slot_impl< KEY, animation_slot::TFORM >275 {276 private:277 struct fallback { int tform; };278 struct derived : KEY, fallback { };279 template<typename C, C> struct cht;280 template<typename C> static char (&test(cht<int fallback::*, &C::tform>*))[1];281 template<typename C> static char (&test(...))[2];282 public:283 static bool const value = sizeof(test<derived>(0)) == 2;;284 };285 286 template < typename KEY, animation_slot SLOT, bool HAS_SLOT >287 struct key_slot_info_impl288 {289 };290 291 template < typename KEY, animation_slot SLOT >292 struct key_slot_info_impl < KEY, SLOT, false >293 {294 typedef empty_type value_type;295 static const datatype etype = datatype::NONE;296 static const int offset = 0;297 };298 299 template < typename KEY >300 struct key_slot_info_impl< KEY, animation_slot::TIME, true >301 {302 typedef decltype( KEY::time ) value_type;303 static const datatype etype = type_to_enum< decltype( KEY::time ) >::type;304 static const int offset = offsetof( KEY, time );305 };306 307 template < typename KEY >308 struct key_slot_info_impl< KEY, animation_slot::POSITION, true >309 {310 typedef decltype( KEY::position ) value_type;311 static const datatype etype = type_to_enum< decltype( KEY::position ) >::type;312 static const int offset = offsetof( KEY, position );313 static void interpolate( KEY& key, const KEY& k1, const KEY& k2, float factor )314 {315 key.position = nv::interpolate( k1.position, k2.position, factor );316 }317 };318 319 template < typename KEY >320 struct key_slot_info_impl< KEY, animation_slot::ROTATION, true >321 {322 typedef decltype( KEY::rotation ) value_type;323 static const datatype etype = type_to_enum< decltype( KEY::rotation ) >::type;324 static const int offset = offsetof( KEY, rotation );325 static void interpolate( KEY& key, const KEY& k1, const KEY& k2, float factor )326 {327 key.rotation = nv::interpolate( k1.rotation, k2.rotation, factor );328 }329 };330 331 template < typename KEY >332 struct key_slot_info_impl< KEY, animation_slot::SCALE, true >333 {334 typedef decltype( KEY::scale ) value_type;335 static const datatype etype = type_to_enum< decltype( KEY::scale ) >::type;336 static const int offset = offsetof( KEY, scale );337 static void interpolate( KEY& key, const KEY& k1, const KEY& k2, float factor )338 {339 key.scale = nv::interpolate( k1.scale, k2.scale, factor );340 }341 };342 343 template < typename KEY >344 struct key_slot_info_impl< KEY, animation_slot::TFORM, true >345 {346 typedef decltype( KEY::tform ) value_type;347 static const datatype etype = type_to_enum< decltype( KEY::tform ) >::type;348 static const int offset = offsetof( KEY, tform );349 static void interpolate( KEY& key, const KEY& k1, const KEY& k2, float factor )350 {351 key.tform = nv::interpolate( k1.tform, k2.tform, factor );352 }353 };354 203 } 204 355 205 356 206 template < typename VT, slot SLOT > … … 365 215 }; 366 216 367 template < typename KEY, animation_slot SLOT >368 struct key_has_slot : public detail::key_has_slot_impl< KEY, SLOT >369 {370 };371 372 373 template < typename KEY, animation_slot SLOT >374 struct key_slot_info : public detail::key_slot_info_impl< KEY, SLOT, detail::key_has_slot_impl< KEY, SLOT >::value >375 {376 };377 378 217 struct vertex_descriptor_slot 379 218 { … … 451 290 }; 452 291 453 struct key_descriptor_slot454 {455 datatype etype;456 uint32 offset;457 animation_slot vslot;458 key_descriptor_slot() : etype(NONE), offset(0), vslot(animation_slot::TIME) {}459 };460 461 struct key_descriptor462 {463 key_descriptor_slot slots[ animation_slot::SLOT_MAX_STORE ];464 uint32 count;465 uint32 size;466 467 key_descriptor() : count(0), size(0) {}468 469 template < typename KEY >470 void initialize()471 {472 count = 0;473 initialize_slot< KEY, animation_slot::TIME >();474 initialize_slot< KEY, animation_slot::POSITION >();475 initialize_slot< KEY, animation_slot::ROTATION >();476 initialize_slot< KEY, animation_slot::SCALE >();477 initialize_slot< KEY, animation_slot::TFORM >();478 size = sizeof( KEY );479 }480 481 bool operator==( const key_descriptor& rhs ) const482 {483 if ( size != rhs.size ) return false;484 if ( count != rhs.count ) return false;485 for ( uint32 i = 0; i < count; ++i )486 {487 if ( slots[i].etype != rhs.slots[i].etype ) return false;488 if ( slots[i].offset != rhs.slots[i].offset ) return false;489 if ( slots[i].vslot != rhs.slots[i].vslot ) return false;490 }491 return true;492 }493 494 private:495 template < typename KEY, animation_slot SLOT >496 void initialize_slot()497 {498 typedef key_slot_info< KEY, SLOT > slot_info;499 slots[ count ].etype = slot_info::etype;500 if ( slots[ count ].etype != datatype::NONE )501 {502 slots[ count ].vslot = SLOT;503 slots[ count ].offset = slot_info::offset;504 count++;505 }506 }507 };508 509 template < typename KEY, animation_slot SLOT >510 void interpolate_slot( KEY& key, const KEY& k1, const KEY& k2, float factor, const std::true_type& )511 {512 key_slot_info< KEY, SLOT >::interpolate( key, k1, k2, factor );513 }514 515 template < typename KEY, animation_slot SLOT >516 void interpolate_slot( KEY&, const KEY&, const KEY&, float, const std::false_type& )517 {518 }519 520 template < typename KEY >521 void interpolate_key( KEY& key, const KEY& k1, const KEY& k2, float factor )522 {523 interpolate_slot< KEY, animation_slot::POSITION >( key, k1, k2, factor, std::integral_constant< bool, key_has_slot< KEY, animation_slot::POSITION >::value >() );524 interpolate_slot< KEY, animation_slot::ROTATION >( key, k1, k2, factor, std::integral_constant< bool, key_has_slot< KEY, animation_slot::ROTATION >::value >() );525 interpolate_slot< KEY, animation_slot::SCALE >( key, k1, k2, factor, std::integral_constant< bool, key_has_slot< KEY, animation_slot::SCALE >::value >() );526 interpolate_slot< KEY, animation_slot::TFORM >( key, k1, k2, factor, std::integral_constant< bool, key_has_slot< KEY, animation_slot::TFORM >::value >() );527 }528 529 namespace detail530 {531 template < typename T >532 mat4 extract_matrix_slot( const T& ) { static_assert( false, "extract_matrix_slot" ); }533 template <> inline mat4 extract_matrix_slot( const mat4& m ) { return m; }534 template <> inline mat4 extract_matrix_slot( const transform& m ) { return m.extract(); }535 536 template < typename T >537 transform extract_transfrom_slot( const T& ) { static_assert( false, "extract_matrix_slot" ); }538 template <> inline transform extract_transfrom_slot( const mat4& m ) { return transform(m); }539 template <> inline transform extract_transfrom_slot( const transform& m ) { return m; }540 541 template < typename KEY >542 mat4 extract_matrix_p_impl( const KEY& k ) { return glm::translate(mat4(),k.position); }543 template < typename KEY >544 mat4 extract_matrix_r_impl( const KEY& k ) { return glm::mat4_cast( k.rotation ); }545 template < typename KEY >546 mat4 extract_matrix_s_impl( const KEY& k ) { return glm::scale(mat4(),k.scale); }547 template < typename KEY >548 mat4 extract_matrix_pr_impl( const KEY& k )549 {550 // TODO: this is obviously unoptimized551 mat4 result = glm::mat4_cast( k.rotation );552 result[3] = vec4( k.position, 1.0f );553 return result;554 }555 template < typename KEY >556 mat4 extract_matrix_rs_impl( const KEY& k )557 {558 // TODO: this is obviously unoptimized559 mat4 result = glm::mat4_cast( k.rotation );560 return glm::scale(result,k.scale);561 }562 template < typename KEY >563 mat4 extract_matrix_ps_impl( const KEY& k )564 {565 // TODO: this is obviously unoptimized566 return glm::scale(glm::translate(mat4(),k.position),k.scale);567 }568 template < typename KEY >569 mat4 extract_matrix_prs_impl( const KEY& k )570 {571 // TODO: this is obviously unoptimized572 return glm::translate(mat4(),k.position) * glm::mat4_cast( k.rotation ) * glm::scale(mat4(),k.scale);573 }574 575 template < typename KEY >576 mat4 extract_matrix_prs( const KEY& k, const std::false_type&, const std::false_type&, const std::false_type& )577 { return mat4(); }578 template < typename KEY >579 mat4 extract_matrix_prs( const KEY& k, const std::true_type&, const std::false_type&, const std::false_type& )580 { return extract_matrix_p_impl(k); }581 template < typename KEY >582 mat4 extract_matrix_prs( const KEY& k, const std::false_type&, const std::true_type&, const std::false_type& )583 { return extract_matrix_r_impl(k); }584 template < typename KEY >585 mat4 extract_matrix_prs( const KEY& k, const std::false_type&, const std::false_type&, const std::true_type& )586 { return extract_matrix_s_impl(k); }587 template < typename KEY >588 mat4 extract_matrix_prs( const KEY& k, const std::true_type&, const std::true_type&, const std::false_type& )589 { return extract_matrix_pr_impl(k); }590 template < typename KEY >591 mat4 extract_matrix_prs( const KEY& k, const std::false_type&, const std::true_type&, const std::true_type& )592 { return extract_matrix_rs_impl(k); }593 template < typename KEY >594 mat4 extract_matrix_prs( const KEY& k, const std::true_type&, const std::false_type&, const std::true_type& )595 { return extract_matrix_ps_impl(k); }596 template < typename KEY >597 mat4 extract_matrix_prs( const KEY& k, const std::true_type&, const std::true_type&, const std::true_type& )598 { return extract_matrix_prs_impl(k); }599 600 601 template < typename KEY >602 transform extract_transform_pr_impl( const KEY& k, const std::false_type&, const std::false_type& ) { return transform(); }603 template < typename KEY >604 transform extract_transform_pr_impl( const KEY& k, const std::true_type&, const std::true_type& ) { return transform( k.position, k.rotation ); }605 template < typename KEY >606 transform extract_transform_pr_impl( const KEY& k, const std::true_type&, const std::false_type& ) { return transform( k.position ); }607 template < typename KEY >608 transform extract_transform_pr_impl( const KEY& k, const std::false_type&, const std::true_type& ) { return transform( k.rotation ); }609 610 611 612 template < typename KEY >613 mat4 extract_matrix_impl( const KEY& k, const std::true_type& )614 {615 static_assert( key_has_slot< KEY, animation_slot::POSITION >::value == false, "key!");616 static_assert( key_has_slot< KEY, animation_slot::ROTATION >::value == false, "key!");617 static_assert( key_has_slot< KEY, animation_slot::SCALE >::value == false, "key!");618 return extract_matrix_slot( k.tform );619 }620 621 template < typename KEY >622 mat4 extract_matrix_impl( const KEY& k, const std::false_type& )623 {624 static_assert( key_has_slot< KEY, animation_slot::TFORM >::value == false, "key!");625 return extract_matrix_prs( k,626 std::integral_constant< bool, key_has_slot< KEY, animation_slot::POSITION >::value >(),627 std::integral_constant< bool, key_has_slot< KEY, animation_slot::ROTATION >::value >(),628 std::integral_constant< bool, key_has_slot< KEY, animation_slot::SCALE >::value >()629 );630 }631 632 template < typename KEY >633 transform extract_transform_impl( const KEY& k, const std::true_type& )634 {635 static_assert( key_has_slot< KEY, animation_slot::POSITION >::value == false, "key!");636 static_assert( key_has_slot< KEY, animation_slot::ROTATION >::value == false, "key!");637 static_assert( key_has_slot< KEY, animation_slot::SCALE >::value == false, "key!");638 return extract_transfrom_slot( k.tform );639 }640 641 template < typename KEY >642 transform extract_transform_impl( const KEY& k, const std::false_type& )643 {644 static_assert( key_has_slot< KEY, animation_slot::TFORM >::value == false, "key!");645 static_assert( key_has_slot< KEY, animation_slot::SCALE >::value == false, "key!");646 return extract_transform_pr_impl( k,647 std::integral_constant< bool, key_has_slot< KEY, animation_slot::POSITION >::value >(),648 std::integral_constant< bool, key_has_slot< KEY, animation_slot::ROTATION >::value >()649 );650 }651 }652 653 template < typename KEY >654 mat4 extract_matrix( const KEY& k )655 {656 return detail::extract_matrix_impl( k, std::integral_constant< bool, key_has_slot< KEY, animation_slot::TFORM >::value >() );657 }658 659 template < typename KEY >660 transform extract_transform( const KEY& k )661 {662 return detail::extract_transform_impl( k, std::integral_constant< bool, key_has_slot< KEY, animation_slot::TFORM >::value >() );663 }664 665 inline uint32 interpolate_raw_linear( uint32 count, float factor, const float* k1, const float* k2, float* result )666 {667 for ( uint32 i = 0; i < count; ++i )668 {669 result[i] = k1[i] + factor * (k2[i] - k1[i]);670 }671 return count;672 }673 674 inline uint32 interpolate_raw_quat( float factor, const float* k1, const float* k2, float* result )675 {676 *((quat*)(result)) = interpolate( *((quat*)(k1)), *((quat*)(k2)), factor );677 return 4;678 }679 680 inline uint32 interpolate_raw( const key_descriptor_slot& slot, float factor, const float* k1, const float* k2, float* result )681 {682 uint32 count = get_datatype_info( slot.etype ).elements;683 switch ( slot.vslot )684 {685 case animation_slot::TIME: return 0;686 case animation_slot::POSITION: return interpolate_raw_linear( count, factor, k1, k2, result );687 case animation_slot::ROTATION: return interpolate_raw_quat( factor, k1, k2, result );688 case animation_slot::SCALE: return interpolate_raw_linear( count, factor, k1, k2, result );689 case animation_slot::TFORM: return690 interpolate_raw_linear( 3, factor, k1, k2, result ) +691 interpolate_raw_quat( factor, k1 + 3, k2 + 3, result + 3 );692 default:693 return 0;694 };695 }696 697 inline quat make_quat_fixed( const float* data )698 {699 quat result;700 memcpy((float*)(&result), data, sizeof(quat));701 return result;702 }703 704 inline mat4 extract_matrix_raw( const key_descriptor& desc, const float* data )705 {706 if ( desc.count == 1 )707 {708 switch ( desc.slots[0].vslot )709 {710 case animation_slot::TIME: return mat4();711 case animation_slot::POSITION: return glm::translate( mat4(),glm::make_vec3( data ) );712 case animation_slot::ROTATION: return glm::mat4_cast( make_quat_fixed( data ) );713 case animation_slot::SCALE: return glm::scale( mat4(),glm::make_vec3( data ) );714 case animation_slot::TFORM: return transform( glm::make_vec3( data ), make_quat_fixed( data + 3 ) ).extract();715 default:716 return mat4();717 };718 }719 else720 {721 mat4 position;722 mat4 rotation;723 mat4 scale;724 for ( uint32 i = 0; i < desc.count; ++i )725 {726 uint32 offset = desc.slots[i].offset / 4;727 switch ( desc.slots[i].vslot )728 {729 case animation_slot::TIME: break;730 case animation_slot::POSITION:731 position = glm::translate( position,glm::make_vec3( data + offset ) ); break;732 case animation_slot::ROTATION:733 rotation = glm::mat4_cast( make_quat_fixed( data + offset ) ); break;734 case animation_slot::SCALE:735 scale = glm::scale( mat4(),glm::make_vec3( data + offset ) ); break;736 case animation_slot::TFORM: return transform( glm::make_vec3( data + offset ), make_quat_fixed( data + offset + 3 ) ).extract();737 default:738 break;739 }740 }741 return position * rotation * scale;742 }743 }744 745 inline transform extract_transform_raw( const key_descriptor& desc, const float* data )746 {747 if ( desc.count == 1 )748 {749 switch ( desc.slots[0].vslot )750 {751 case animation_slot::TIME: return transform();752 case animation_slot::POSITION: return transform( glm::make_vec3( data ) );753 case animation_slot::ROTATION: return transform( make_quat_fixed( data ) );754 case animation_slot::SCALE: return transform();755 case animation_slot::TFORM: return transform( glm::make_vec3( data ), make_quat_fixed( data + 3 ) );756 default:757 return transform();758 };759 }760 else761 {762 vec3 position;763 quat rotation;764 for ( uint32 i = 0; i < desc.count; ++i )765 {766 uint32 offset = desc.slots[i].offset / 4;767 switch ( desc.slots[i].vslot )768 {769 case animation_slot::TIME: break;770 case animation_slot::POSITION:771 position = glm::make_vec3( data + offset ); break;772 case animation_slot::ROTATION:773 rotation = make_quat_fixed( data + offset ); break;774 case animation_slot::SCALE: break;775 case animation_slot::TFORM: return transform( glm::make_vec3( data + offset ), make_quat_fixed( data + 3 ) );776 default:777 break;778 }779 }780 return transform( position, rotation );781 }782 }783 784 292 } 785 293
Note: See TracChangeset
for help on using the changeset viewer.