Changeset 286


Ignore:
Timestamp:
07/21/14 02:42:49 (11 years ago)
Author:
epyon
Message:
  • split the monolithic animation templates into separate headers
  • vertex.hh no longer has any animated key templates
Location:
trunk/nv
Files:
3 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/gfx/animation.hh

    r285 r286  
    1212#include <nv/interface/stream.hh>
    1313#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>
    1517#include <nv/transform.hh>
    1618#include <glm/gtc/matrix_transform.hpp>
  • trunk/nv/interface/vertex.hh

    r285 r286  
    3232        };
    3333
    34         enum class animation_slot : uint8
    35         {
    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 
    4634        namespace detail
    4735        {
     
    213201                };
    214202
    215                 template < typename KEY, animation_slot SLOT >
    216                 struct key_has_slot_impl
    217                 {
    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_impl
    288                 {
    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                 };
    354203        }
     204
    355205
    356206        template < typename VT, slot SLOT >
     
    365215        };
    366216
    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        
    378217        struct vertex_descriptor_slot
    379218        {
     
    451290        };
    452291
    453         struct key_descriptor_slot
    454         {
    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_descriptor
    462         {
    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 ) const
    482                 {
    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 detail
    530         {
    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 unoptimized
    551                         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 unoptimized
    559                         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 unoptimized
    566                         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 unoptimized
    572                         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:    return
    690                                                                                    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                 else
    720                 {
    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                 else
    761                 {
    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 
    784292}
    785293
Note: See TracChangeset for help on using the changeset viewer.