Changeset 282


Ignore:
Timestamp:
07/10/14 00:29:34 (11 years ago)
Author:
epyon
Message:
  • key_slots - another template hell similar to vertex definitions
  • animation data is now stored using key_raw_channel's similarly to mesh_raw_channels
  • automatic compile-time templated interpolation generation for any type of animation key
  • QUAT and TRANSFORM as registered types for channels
  • a ton of minor cleanups
  • do not open vertex.hh if you want to stay sane
Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/formats/assimp_loader.hh

    r280 r282  
    1616namespace nv
    1717{
     18        struct assimp_key_p  { float time; vec3 position; };
     19        struct assimp_key_r  { float time; quat rotation; };
     20        struct assimp_key_s  { float time; vec3 scale; };
     21        struct assimp_key_tr { transform tform; };
     22
    1823
    1924        struct assimp_bone
     
    3742                sint32                parent_id;
    3843                mat4                  transform;
    39                 key_animation_data*   keys;
    40                 sint32                bone_id;   // reconstructed
    41                 std::vector< assimp_animated_node_data* > children;  // reconstructed
     44                uint16                channel_count;
     45                key_raw_channel*      channels[4];
    4246
    43                 assimp_animated_node_data() : name(), parent_id( -1 ), keys( nullptr ), bone_id( -1 ) {}
     47                assimp_animated_node_data()
     48                        : name(), parent_id( -1 )
     49                {
     50                        channels[0] = nullptr; channels[1] = nullptr; channels[2] = nullptr; channels[3] = nullptr;
     51                }
    4452                ~assimp_animated_node_data()
    4553                {
    46                         if ( keys ) delete keys;
     54                        if ( channels[0] ) delete channels[0];
     55                        if ( channels[1] ) delete channels[1];
     56                        if ( channels[2] ) delete channels[2];
     57                        if ( channels[3] ) delete channels[3];
    4758                }
    4859        };
     
    5364                float duration;
    5465                bool  pretransformed;
    55                 std::vector< assimp_animated_node_data > nodes; // read-only!
     66                dynamic_array< assimp_animated_node_data > nodes;
    5667        };
    57 
    58 
    5968
    6069        class assimp_loader : public mesh_loader
     
    6877                virtual ~assimp_loader();
    6978                assimp_model* release_merged_model();
    70                 assimp_animation* release_animation( size_t index, bool pre_transform, const std::vector< assimp_bone >* bone_data );
     79                assimp_animation* release_animation( size_t index, bool pre_transform );
    7180                bool load_bones( size_t index, std::vector< assimp_bone >& bones );
    7281                void scene_report() const;
     
    7483                uint32 load_node( assimp_animation* data, const void* vnode, sint32 this_id, sint32 parent_id );
    7584                uint32 count_nodes( const void* node ) const;
    76                 key_animation_data* create_transformed_keys( const void* vnode, const key_animation_data* parent_keys );
    77                 key_animation_data* create_direct_keys( const void* vnode );
     85                void create_transformed_keys( assimp_animated_node_data* data, const void* vnode, const assimp_animated_node_data* parent );
     86                void create_direct_keys( assimp_animated_node_data* data, const void* vnode );
    7887
    7988                string_table_creator m_strings;
  • trunk/nv/formats/md3_loader.hh

    r241 r282  
    2323namespace nv
    2424{
     25        struct md3_key
     26        {
     27                transform tform;
     28        };
     29
    2530
    2631        class md3_loader : public mesh_loader
     
    3641                virtual tag_map* create_tag_map();
    3742        private:
    38                 void load_tags( transform_vector& t, const std::string& tag );
     43                key_raw_channel* load_tags( const std::string& tag );
    3944                void* m_md3;
    40 
    41                 struct md3_tag
    42                 {
    43                         std::string name;
    44                         transform   trans;
    45                 };
    46 
    47                 std::unordered_map< std::string, md3_tag > m_tags;
    4845        };
    4946
  • trunk/nv/formats/md5_loader.hh

    r261 r282  
    5757                struct md5_joint
    5858                {
    59                         int              parent;
    60                         transform_vector keys;
     59                        int                      parent;
     60                        std::vector< transform > keys;
    6161
    62                         md5_joint( int a_parent, size_t reserve ) : parent( a_parent ) { keys.reserve( reserve ); }
     62                        md5_joint( int a_parent ) : parent( a_parent ) {}
    6363                };
    6464
  • trunk/nv/gfx/animation.hh

    r281 r282  
    1212#include <nv/interface/stream.hh>
    1313#include <nv/math.hh>
     14#include <nv/interface/vertex.hh>
    1415#include <nv/transform.hh>
    1516#include <glm/gtc/matrix_transform.hpp>
     
    1819{
    1920
    20         // TODO: time sorting or check?
    21         template < typename KEY >
    22         class key_vector
    23         {
    24         public:
    25                 struct key
    26                 {
    27                         float time;
    28                         KEY   value;
    29                         key() {}
    30                         key( float a_time, const KEY& a_value ) : time(a_time), value(a_value) {}
    31                 };
    32                 key_vector() {}
    33                 void insert( float a_time, const KEY& a_key ) { m_keys.emplace_back( a_time, a_key ); }
    34                 size_t size() const { return m_keys.size(); }
    35                 const key* data() const { return m_keys.data(); }
    36                 const KEY& get( size_t index ) const { return m_keys[index]; }
    37                 KEY get_interpolated( float time ) const
    38                 {
    39                         if ( m_keys.size() == 0 ) return KEY();
    40                         if ( m_keys.size() == 1 ) return m_keys[0].value;
     21        struct key_raw_channel
     22        {
     23                key_descriptor desc;
     24                uint8*         data;
     25                uint32         count;
     26
     27                key_raw_channel() : data( nullptr ), count( 0 ) {}
     28                ~key_raw_channel()
     29                {
     30                        if ( data != nullptr ) delete[] data;
     31                }
     32
     33                uint32 size() const { return count * desc.size; }
     34
     35                template < typename KEY >
     36                static key_raw_channel* create( uint32 count = 0 )
     37                {
     38                        key_raw_channel* result = new key_raw_channel();
     39                        result->desc.initialize<KEY>();
     40                        result->count = count;
     41                        result->data  = (count > 0 ? ( new uint8[ result->size() ] ) : nullptr );
     42                        return result;
     43                }
     44
     45                static key_raw_channel* create( const key_descriptor& keydesc, uint32 count = 0 )
     46                {
     47                        key_raw_channel* result = new key_raw_channel();
     48                        result->desc  = keydesc;
     49                        result->count = count;
     50                        result->data  = (count > 0 ? ( new uint8[ result->size() ] ) : nullptr );
     51                        return result;
     52                }
     53        };
     54
     55        class key_data
     56        {
     57        public:
     58                key_data() {}
     59
     60                void add_channel( key_raw_channel* channel )
     61                {
     62                        NV_ASSERT( channel, "nullptr passed to add_channel!" );
     63                        m_channels.push_back( channel );
     64                }
     65
     66                virtual ~key_data()
     67                {
     68                        for ( auto channel : m_channels ) delete channel;
     69                }
     70        private:
     71                std::vector< key_raw_channel* > m_channels;
     72        };
     73
     74        template < typename KEY, bool TIMED >
     75        class key_channel_interpolator;
     76
     77
     78        template < typename KEY >
     79        class key_channel_interpolator< KEY, false >
     80        {
     81        public:
     82                key_channel_interpolator() : m_data( nullptr ) {}
     83                key_channel_interpolator( key_raw_channel* data ) : m_data( nullptr ) { set_data( data ); }
     84                key_channel_interpolator( key_raw_channel* data, bool ) : m_data( data ) {}
     85                void set_data( key_raw_channel* data )
     86                {
     87                        m_data = data;
     88                        key_descriptor desc;
     89                        desc.initialize<KEY>();
     90                        NV_ASSERT( data->desc == desc, "Bad channel passed!" );
     91                }
     92                void get_interpolated( KEY& result, float frame ) const
     93                {
     94                        NV_ASSERT( m_data, "Data is null!" );
     95                        if ( m_data->count == 0 ) return;
     96                        if ( m_data->count == 1 )
     97                        {
     98                                result = ((KEY*)m_data->data)[0];
     99                                return;
     100                        }
     101                        size_t index = glm::clamp<size_t>( size_t( frame ), 0, m_data->count - 2 );
     102                        float factor = glm::clamp<float> ( frame - index, 0.0f, 1.0f );
     103                        KEY* keys = ((KEY*)m_data->data);
     104                        interpolate_key( result, keys[index], keys[index+1], factor );
     105                }
     106
     107        private:
     108                key_raw_channel* m_data;
     109        };
     110 
     111        template < typename KEY >
     112        class key_channel_interpolator< KEY, true >
     113        {
     114        public:
     115                key_channel_interpolator() : m_data( nullptr ) {}
     116                key_channel_interpolator( key_raw_channel* data ) : m_data( nullptr ) { set_data( data ); }
     117                void set_data( key_raw_channel* data )
     118                {
     119                        m_data = data;
     120                        key_descriptor desc;
     121                        desc.initialize<KEY>();
     122                        NV_ASSERT( data->desc == desc, "Bad channel passed!" );
     123                }
     124                void get_interpolated( KEY& result, float time ) const
     125                {
     126                        // TODO: this probably could be optimized
     127                        const KEY* keys = (const KEY*)(m_data->data);
     128                        NV_ASSERT( m_data, "Data is null!" );
     129                        if ( m_data->count == 0 ) return;
     130                        if ( m_data->count == 1 )
     131                        {
     132                                result = keys[0];
     133                                return;
     134                        }
    41135                        int index = -1;
    42                         for ( int i = 0 ; i < (int)m_keys.size() - 1 ; i++ )
     136                        for ( int i = 0 ; i < (int)m_data->count - 1 ; i++ )
    43137                        {
    44                                 if ( time < m_keys[i + 1].time ) { index = i; break; }
     138                                if ( time < keys[i + 1].time ) { index = i; break; }
    45139                        }
    46140                        NV_ASSERT( index >= 0, "animation time fail!");
    47                         float delta  = m_keys[index + 1].time - m_keys[index].time;
    48                         float factor = glm::clamp( (time - m_keys[index].time) / delta, 0.0f, 1.0f );
    49                         return interpolate( m_keys[index].value, m_keys[index + 1].value, factor );
    50                 }
    51                 virtual uint32 raw_size() const
    52                 {
    53                         return sizeof( size_t ) + m_keys.size() * sizeof( key );
    54                 }
    55                 virtual void dump( stream* out_stream ) const
    56                 {
    57                         size_t sz = m_keys.size();
    58                         out_stream->write( &sz, sizeof( size_t ), 1 );
    59                         if ( sz > 0 )
    60                         {
    61                                 out_stream->write( &m_keys[0], sizeof( key ), sz );
    62                         }
    63                 }
    64                 virtual void load( stream* in_stream )
    65                 {
    66                         size_t sz;
    67                         in_stream->read( &sz, sizeof( size_t ), 1 );
    68                         if ( sz > 0 )
    69                         {
    70                                 m_keys.resize( sz );
    71                                 in_stream->read( &m_keys[0], sizeof( key ), sz );
    72                         }
    73                 }
    74         protected:
    75                 std::vector< key > m_keys;
    76         };
     141                        float delta  = keys[index + 1].time - keys[index].time;
     142                        float factor = glm::clamp( (time - keys[index].time) / delta, 0.0f, 1.0f );
     143                        interpolate_key( result, keys[index], keys[index+1], factor );
     144                }
     145
     146        private:
     147                key_raw_channel* m_data;
     148        };
     149 
     150//      template < typename KEY1, typename KEY2 = void, typename KEY3 = void >
     151//      class key_data_interpolator
     152//      {
     153//
     154//      };
    77155
    78156        class key_animation_data
     
    81159                virtual mat4 get_matrix( float time ) const = 0;
    82160                virtual transform get_transform( float time ) const = 0;
    83                 virtual void dump( stream* out_stream ) const = 0;
    84                 virtual void load( stream* in_stream ) = 0;
    85161                virtual bool empty() const = 0;
     162                virtual size_t size() const = 0;
    86163                virtual uint32 raw_size() const = 0;
    87164                virtual ~key_animation_data() {}
     
    91168        class key_vectors_prs : public key_animation_data
    92169        {
    93         public:
    94                 key_vectors_prs() {}
    95                 void insert_position( float a_time, const vec3& a_value ) { m_positions.insert( a_time, a_value ); }
    96                 void insert_rotation( float a_time, const quat& a_value ) { m_rotations.insert( a_time, a_value ); }
    97                 void insert_scale   ( float a_time, const vec3& a_value ) { m_scales.insert( a_time, a_value ); }
    98                 bool empty() const { return m_positions.size() == 0 && m_rotations.size() == 0 && m_scales.size() == 0; }
     170                struct key_p { float time; vec3 position; };
     171                struct key_r { float time; quat rotation; };
     172                struct key_s { float time; vec3 scale; };
     173        public:
     174                explicit key_vectors_prs( key_raw_channel* p, key_raw_channel* r, key_raw_channel* s )
     175                {
     176                        m_pchannel = p;
     177                        m_rchannel = r;
     178                        m_schannel = s;
     179                        m_pinter.set_data( m_pchannel );
     180                        m_rinter.set_data( m_rchannel );
     181                        m_sinter.set_data( m_schannel );
     182                }
     183                size_t size() const { return 0; } // TODO: remove?
     184                bool empty() const { return m_pchannel->count == 0 && m_rchannel->count == 0 && m_schannel->count == 0; }
    99185                virtual mat4 get_matrix( float time ) const
    100186                {
    101                         nv::mat4 position;
    102                         nv::mat4 rotation;
    103                         nv::mat4 scaling;
    104 
    105                         if ( m_positions.size() > 0 ) position = glm::translate( position, m_positions.get_interpolated( time ) );
    106                         if ( m_rotations.size() > 0 ) rotation = glm::mat4_cast( m_rotations.get_interpolated( time ) );
    107                         if ( m_scales.size()    > 0 ) scaling  = glm::scale( scaling, m_scales.get_interpolated( time ) );
    108 
    109                         return position * rotation * scaling;
     187                        key_p p;
     188                        key_r r;
     189                        key_s s;
     190
     191                        m_pinter.get_interpolated( p, time );
     192                        m_rinter.get_interpolated( r, time );
     193                        m_sinter.get_interpolated( s, time );
     194
     195                        return extract_matrix( p ) * extract_matrix( r ) * extract_matrix( s );
    110196                }
    111197                virtual transform get_transform( float time ) const
    112198                {
    113                         transform result;
    114                         if ( m_positions.size() > 0 ) result.set_position( m_positions.get_interpolated( time ) );
    115                         if ( m_rotations.size() > 0 ) result.set_orientation( m_rotations.get_interpolated( time ) );
    116                         return result;
     199                        key_p p;
     200                        key_r r;
     201
     202                        m_pinter.get_interpolated( p, time );
     203                        m_rinter.get_interpolated( r, time );
     204
     205                        return transform( p.position, r.rotation );
    117206                }
    118207                virtual uint32 raw_size() const
    119208                {
    120                         return m_positions.raw_size() + m_rotations.raw_size() + m_scales.raw_size();
    121                 }
    122                 virtual void dump( stream* out_stream ) const
    123                 {
    124                         m_positions.dump( out_stream );
    125                         m_rotations.dump( out_stream );
    126                         m_scales.dump( out_stream );
    127                 }
    128                 virtual void load( stream* in_stream )
    129                 {
    130                         m_positions.load( in_stream );
    131                         m_rotations.load( in_stream );
    132                         m_scales.load( in_stream );
     209                        return 3 * sizeof( size_t )
     210                                + m_pchannel->count * sizeof( key_p )
     211                                + m_rchannel->count * sizeof( key_r )
     212                                + m_schannel->count * sizeof( key_s );
     213                }
     214                ~key_vectors_prs()
     215                {
    133216                }
    134217        protected:
    135                 key_vector< nv::vec3 > m_positions;
    136                 key_vector< nv::quat > m_rotations;
    137                 key_vector< nv::vec3 > m_scales;
     218                key_raw_channel* m_pchannel;
     219                key_raw_channel* m_rchannel;
     220                key_raw_channel* m_schannel;
     221                key_channel_interpolator< key_p, true > m_pinter;
     222                key_channel_interpolator< key_r, true > m_rinter;
     223                key_channel_interpolator< key_s, true > m_sinter;
    138224        };
    139225
    140226        class transform_vector : public key_animation_data
    141227        {
    142         public:
    143                 transform_vector() {}
    144                 void reserve( size_t sz ) { m_keys.reserve( sz ); }
    145                 void insert( const transform& t ) { m_keys.push_back( t ); }
    146                 bool empty() const { return m_keys.empty(); }
    147                 size_t size() const { return m_keys.size(); }
    148                 const transform& get( size_t index ) const { return m_keys[ index ]; }
    149                 const transform* data() const { return m_keys.data(); }
     228                struct key
     229                {
     230                        transform tform;
     231                };
     232        public:
     233                explicit transform_vector( key_raw_channel* channel )
     234                {
     235                        key_descriptor kd;
     236                        kd.initialize<key>();
     237                        NV_ASSERT( kd == channel->desc, "bad channel!" );
     238                        m_channel = channel;
     239                        m_interpolator.set_data( m_channel );
     240                }
     241
     242                ~transform_vector()
     243                {
     244                        delete m_channel;
     245                }
     246                bool empty() const { return m_channel->count == 0; }
     247                size_t size() const { return m_channel->count; }
     248                const transform& get( size_t index ) const { return ((key*)(m_channel->data))[ index ].tform; }
     249                const transform* data() const { return (const transform*)m_channel->data; }
    150250
    151251                virtual uint32 raw_size() const
    152252                {
    153                         return sizeof( size_t ) + m_keys.size() * sizeof( transform );
    154                 }
    155 
    156                 virtual void dump( stream* out_stream ) const
    157                 {
    158                         size_t sz = m_keys.size();
    159                         out_stream->write( &sz, sizeof( size_t ), 1 );
    160                         if ( sz > 0 )
    161                         {
    162                                 out_stream->write( &m_keys[0], sizeof( transform ), sz );
    163                         }
    164                 }
    165                 virtual void load( stream* in_stream )
    166                 {
    167                         size_t sz;
    168                         in_stream->read( &sz, sizeof( size_t ), 1 );
    169                         if ( sz > 0 )
    170                         {
    171                                 m_keys.resize( sz );
    172                                 in_stream->read( &m_keys[0], sizeof( transform ), sz );
    173                         }
    174                 }
     253                        return sizeof( size_t ) + m_channel->count * sizeof( key );
     254                }
     255
    175256                virtual mat4 get_matrix( float time ) const
    176257                {
     
    179260                virtual transform get_transform( float time ) const
    180261                {
    181                         if ( m_keys.size() == 0 ) return transform();
    182                         if ( m_keys.size() == 1 ) return m_keys[0];
    183                         size_t index = glm::clamp<size_t>( size_t( time ), 0, m_keys.size() - 2 );
    184                         float factor = glm::clamp<float> ( time - index, 0.0f, 1.0f );
    185                         return interpolate( m_keys[ index ], m_keys[ index + 1 ], factor );
     262                        key result;
     263                        m_interpolator.get_interpolated( result, time );
     264                        return extract_transform< key >( result );
    186265                }
    187266        protected:
    188                 std::vector< transform > m_keys;
    189         };
     267                key_channel_interpolator< key, false > m_interpolator;
     268                key_raw_channel* m_channel;
     269        };
     270
    190271
    191272}
  • trunk/nv/interface/mesh_loader.hh

    r241 r282  
    2626{
    2727
     28        // TODO: change to generic nodes!
    2829        class tag_map
    2930        {
    3031        public:
    31                 typedef std::unordered_map< std::string, transform_vector > map;
     32                typedef std::unordered_map< std::string, key_raw_channel* > map;
    3233
    3334                tag_map () {}
    34                 map& get_map()             { return m_map; }
    35                 const map& get_map() const { return m_map; }
    36                 const transform_vector* get_tag( const std::string& key ) const
     35
     36                const transform* get_tag( const std::string& key ) const
    3737                {
    38                         auto it = m_map.find( key );
    39                         return ( it != m_map.end() ? &(it->second) : nullptr );
     38                        key_raw_channel* channel = m_map.at( key );
     39                        return ((transform*)(channel->data));
     40                }
     41                void insert( const std::string& key, key_raw_channel* chan )
     42                {
     43                        m_map[ key ] = chan;
     44                }
     45                ~tag_map()
     46                {
     47                        for ( auto t : m_map )
     48                                delete t.second;
    4049                }
    4150        private:
  • trunk/nv/interface/vertex.hh

    r281 r282  
    1111
    1212#include <nv/common.hh>
     13#include <nv/transform.hh>
    1314#include <nv/math.hh>
    1415
     
    3132        };
    3233
    33         enum animation_slot
    34         {
    35 //              TIME     = 0,
    36 //              POSITION = 1,
    37 //              ROTATION = 2,
    38 //              SCALE    = 3,
    39 //              MATRIX   = 4,
    40 //              ANIM_SLOT_MAX       = 4,
    41 //              ANIM_SLOT_MAX_STORE = 5,
     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,
    4244        };
    4345
     
    217219                };
    218220
     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                };
    219354        }
    220355
     
    230365        };
    231366
     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       
    232378        struct vertex_descriptor_slot
    233379        {
     
    235381                uint32   offset;
    236382                slot     vslot;
    237                 vertex_descriptor_slot() : etype(NONE), offset(0), vslot(slot::POSITION) {}
    238383        };
    239384
     
    243388                uint32                 count;
    244389                uint32                 size;
    245 
    246                 vertex_descriptor() : count(0), size(0) {}
    247390
    248391                template < typename IDX >
     
    308451        };
    309452
     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 )
     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
    310665}
    311666
  • trunk/nv/math.hh

    r241 r282  
    104104                BYTE_VECTOR_3,
    105105                BYTE_VECTOR_4,
     106                QUAT,
     107                TRANSFORM,
    106108                DATATYPE_COUNT,
    107109        };
     
    138140                        { 1 * 3,  BYTE, 3 },  // BYTE_VECTOR_3,
    139141                        { 1 * 4,  BYTE, 4 },  // BYTE_VECTOR_4,
     142                        { 4 * 4,  FLOAT, 4 },      // QUAT,
     143                        { 7 * 4,  FLOAT, 7 },      // TRANSFORM,
    140144                };
    141145                return info[dt];
     
    168172        template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; };
    169173        template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; };
     174
     175        template <> struct enum_to_type< QUAT > { typedef quat type; };
    170176
    171177        template < typename TYPE > struct type_to_enum {};
     
    197203        template <> struct type_to_enum< mat3 > { static const datatype type = FLOAT_MATRIX_3; };
    198204        template <> struct type_to_enum< mat4 > { static const datatype type = FLOAT_MATRIX_4; };
     205        template <> struct type_to_enum< quat > { static const datatype type = QUAT; };
    199206
    200207        template < typename T >
  • trunk/nv/transform.hh

    r261 r282  
    2020                explicit transform( const vec3& a_position ) : m_position( a_position ) {}
    2121                explicit transform( const quat& a_orientation ) : m_orientation( a_orientation ) {}
     22                explicit transform( const mat4& a_matrix ) { set( a_matrix ); }
    2223                transform( const vec3& a_position, const quat& a_orientation ) : m_position( a_position ), m_orientation( a_orientation ) {}
    2324
     
    9192        }
    9293
    93 
     94        template <> struct enum_to_type< TRANSFORM > { typedef transform type; };
     95        template <> struct type_to_enum< transform > { static const datatype type = TRANSFORM; };
    9496
    9597        template<>
  • trunk/src/formats/assimp_loader.cc

    r280 r282  
    314314}
    315315
    316 assimp_animation* nv::assimp_loader::release_animation( size_t, bool pre_transform, const std::vector< assimp_bone >* bone_data )
     316assimp_animation* nv::assimp_loader::release_animation( size_t, bool pre_transform )
    317317{
    318318        if ( m_scene == nullptr ) return nullptr;
     
    332332
    333333        load_node( result, root, 0, -1 );
    334         // TODO: this is not used when pretransformed, is it used otherwise?
    335 
    336         if ( bone_data )
    337         {
    338                 std::unordered_map< std::string, uint16 > names;
    339                 for ( uint16 bi = 0; bi < bone_data->size(); ++bi )
    340                 {
    341                         names[ (*bone_data)[bi].name ] = bi;
    342                 }
    343 
    344                 for ( unsigned i = 0; i < result->nodes.size(); ++i )
    345                 {
    346                         assimp_animated_node_data& node = result->nodes[i];
    347                         node.bone_id = -1;
    348                         auto bi = names.find( node.name );
    349                         if ( bi != names.end() )
    350                         {
    351                                 node.bone_id = bi->second;
    352                         }
    353                         if ( node.parent_id != -1 )
    354                         {
    355                                 result->nodes[ node.parent_id ].children.push_back( &node );
    356                         }
    357                 }
    358         }
    359 
    360334        return result;
    361335}
     
    391365        a_data.name      = name;
    392366        a_data.parent_id = parent_id;
    393         a_data.bone_id = -1;
    394367        // This value is ignored by the create_transformed_keys, but needed by create_direct_keys!
    395368        // TODO: find a common solution!
     
    397370        //       node's without keys
    398371        a_data.transform = nv::assimp_mat4_cast( node->mTransformation );
     372        a_data.channel_count = 0;
    399373
    400374        if (anode)
     
    402376                if ( data->pretransformed )
    403377                {
    404                         a_data.keys = create_transformed_keys( anode, parent_id >= 0 ? data->nodes[ parent_id ].keys : nullptr );
     378                        create_transformed_keys( &a_data, anode, parent_id >= 0 ? &(data->nodes[ parent_id ]) : nullptr );
    405379                }
    406380                else
    407381                {
    408                         a_data.keys = create_direct_keys( anode );
     382                        create_direct_keys( &a_data, anode );
    409383                }
    410384        }
     
    418392}
    419393
    420 key_animation_data* nv::assimp_loader::create_transformed_keys( const void* vnode, const key_animation_data* parent_keys )
     394void nv::assimp_loader::create_transformed_keys( assimp_animated_node_data* data, const void* vnode, const assimp_animated_node_data* parent )
    421395{
    422396        const aiNodeAnim* node = (const aiNodeAnim*)vnode;
    423397        size_t max_keys = glm::max( node->mNumPositionKeys, node->mNumRotationKeys );
    424         nv::transform_vector* keys = new nv::transform_vector;
     398
     399        data->channel_count = 1;
     400        data->channels[0] = key_raw_channel::create<assimp_key_tr>( max_keys );
     401        assimp_key_tr* channel = ((assimp_key_tr*)(data->channels[0]->data));
     402
    425403        for ( unsigned n = 0; n < max_keys; ++n )
    426404        {
     
    431409                // TODO: only do the calculation when a rotate transform is present!
    432410                nv::transform ptr( vec3(), glm::quat_cast( m_rotate_transform ) );
    433                 if ( parent_keys )
    434                 {
    435                         const nv::transform_vector* pv = (const nv::transform_vector*)parent_keys;
    436                         if ( pv && pv->size() > 0 ) ptr = pv->get( glm::min( n, pv->size()-1 ) );
     411                if ( parent )
     412                {
     413                        key_raw_channel* pchannel = parent->channels[0];
     414                        if ( parent->channels[0] && parent->channels[0]->count > 0 )
     415                        {
     416                                ptr = ((assimp_key_tr*)pchannel->data)[ glm::min( n, parent->channels[0]->count-1 ) ].tform;
     417                        }
    437418                }
    438419                nv::transform key( ptr * nv::transform( pos * m_scale, rot ) );
    439                 keys->insert( key );
    440         }
    441         return keys;
    442 }
    443 
    444 key_animation_data* nv::assimp_loader::create_direct_keys( const void* vnode )
    445 {
     420                channel[n].tform = key;
     421        }
     422}
     423
     424void nv::assimp_loader::create_direct_keys( assimp_animated_node_data* data, const void* vnode )
     425{
     426        data->channel_count = 0;
    446427        // TODO : support for m_rotate_transform and m_scale! ( should be easy )
    447428        const aiNodeAnim* node = (const aiNodeAnim*)vnode;
    448         if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 ) return nullptr;
    449         key_vectors_prs* keys = new key_vectors_prs;
     429        if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 )
     430        {
     431                return;
     432        }
     433
     434        data->channel_count = 3;
     435        data->channels[0] = key_raw_channel::create<assimp_key_p>( node->mNumPositionKeys );
     436        data->channels[1] = key_raw_channel::create<assimp_key_r>( node->mNumRotationKeys );
     437        data->channels[2] = key_raw_channel::create<assimp_key_s>( node->mNumScalingKeys );
     438        assimp_key_p* pchannel = ((assimp_key_p*)(data->channels[0]->data));
     439        assimp_key_r* rchannel = ((assimp_key_r*)(data->channels[1]->data));
     440        assimp_key_s* schannel = ((assimp_key_s*)(data->channels[2]->data));
    450441
    451442        for ( unsigned np = 0; np < node->mNumPositionKeys; ++np )
    452443        {
    453                 keys->insert_position( (float)node->mPositionKeys[np].mTime, m_scale * assimp_vec3_cast(node->mPositionKeys[np].mValue) );
     444                pchannel[np].time     = (float)node->mPositionKeys[np].mTime;
     445                pchannel[np].position = assimp_vec3_cast(node->mPositionKeys[np].mValue);
    454446        }
    455447        for ( unsigned np = 0; np < node->mNumRotationKeys; ++np )
    456448        {
    457                 keys->insert_rotation( (float)node->mRotationKeys[np].mTime, assimp_quat_cast(node->mRotationKeys[np].mValue) );
     449                rchannel[np].time     = (float)node->mRotationKeys[np].mTime;
     450                rchannel[np].rotation = assimp_quat_cast(node->mRotationKeys[np].mValue);
    458451        }
    459452        if ( node->mNumScalingKeys > 0 )
     
    466459                        for ( unsigned np = 0; np < node->mNumRotationKeys; ++np )
    467460                        {
    468                                 keys->insert_scale( (float)node->mScalingKeys[np].mTime, assimp_vec3_cast(node->mScalingKeys[np].mValue) );
    469                         }
    470                 }
    471         }
    472         return keys;
    473 }
    474 
     461                                schannel[np].time  = (float)node->mScalingKeys[np].mTime;
     462                                schannel[np].scale = assimp_vec3_cast(node->mScalingKeys[np].mValue);
     463                        }
     464                }
     465        }
     466}
     467
  • trunk/src/formats/md3_loader.cc

    r280 r282  
    275275bool nv::md3_loader::load( stream& source )
    276276{
    277         m_tags.clear();
    278 
    279277        m_md3 = (void*)(new md3_t);
    280278        if ( !read_md3( (md3_t*)m_md3, source ) )
     
    285283}
    286284
    287 void nv::md3_loader::load_tags( transform_vector& t, const std::string& tag )
     285nv::key_raw_channel* nv::md3_loader::load_tags( const std::string& tag )
    288286{
    289287        md3_t* md3 = (md3_t*)m_md3;
     288        key_raw_channel* result = key_raw_channel::create<md3_key>( md3->header.num_frames );
     289        // TODO: is this brain damaged in efficiency (loop nest order) or what?
    290290        for ( sint32 f = 0; f < md3->header.num_frames; ++f )
    291291        {
     
    300300                                vec3 axisy  ( md3_vec3( rtag.axis[2] ) );
    301301                                vec3 origin ( md3_vec3( rtag.origin )  );
    302                                 t.insert( transform( origin, quat( mat3( axisx, axisy, axisz ) ) ) );
     302                                ((md3_key*)(result->data))[f].tform = transform( origin, quat( mat3( axisx, axisy, axisz ) ) );
    303303                        }
    304304                }
    305305
    306306        }
     307        return result;
    307308}
    308309
     
    408409                const md3_tag_t& rtag = md3->tags[i + md3->header.num_tags];
    409410                std::string name( (char*)(rtag.name) );
    410                 load_tags( result->get_map()[ name ], name );
     411                nv::key_raw_channel* keys = load_tags( name );
     412                result->insert( name, keys );
    411413        }
    412414        return result;
  • trunk/src/formats/md5_loader.cc

    r280 r282  
    397397                                remove_quotes( joint.name );
    398398                                joint_infos.push_back( joint );
    399                                 m_joints.push_back( md5_joint( joint.parent_id, m_num_frames ) );
     399                                m_joints.emplace_back( joint.parent_id );
    400400                                next_line( sstream );
    401401                        }
     
    490490        for ( size_t i = 0; i < m_num_joints; ++i )
    491491        {
    492                 const transform_vector& keys = m_joints[i].keys;
    493                 skeleton[i] = interpolate( keys.get(frame0), keys.get(frame1), interpolation );
     492                const std::vector< transform >& keys = m_joints[i].keys;
     493                skeleton[i] = interpolate( keys[frame0], keys[frame1], interpolation );
    494494        }
    495495}
     
    519519                if ( parent_id >= 0 ) // Has a parent joint
    520520                {
    521                         const transform_vector& ptv = m_joints[ size_t( parent_id ) ].keys;
     521                        const std::vector< transform >& ptv = m_joints[ size_t( parent_id ) ].keys;
    522522                        transform ptr;
    523                         if ( ptv.size() > index ) ptr = ptv.get( index );
     523                        if ( ptv.size() > index ) ptr = ptv[ index ];
    524524                        glm::vec3 rot_pos = ptr.get_orientation() * pos;
    525525
     
    530530                }
    531531
    532                 m_joints[i].keys.insert( transform( pos, orient ) );
     532                m_joints[i].keys.push_back( transform( pos, orient ) );
    533533        }
    534534}
  • trunk/src/gfx/keyframed_mesh.cc

    r281 r282  
    4444{
    4545        NV_ASSERT( m_tag_map, "TAGMAP FAIL" );
    46         const transform_vector* transforms = m_tag_map->get_tag( tag );
     46        const transform* transforms = m_tag_map->get_tag( tag );
    4747        NV_ASSERT( transforms, "TAG FAIL" );
    48         return interpolate( transforms->get( m_last_frame ), transforms->get( m_next_frame ), m_interpolation  );
     48        return interpolate( transforms[ m_last_frame ], transforms[ m_next_frame ], m_interpolation  );
    4949}
    5050
Note: See TracChangeset for help on using the changeset viewer.