Index: trunk/nv/gfx/animation.hh
===================================================================
--- trunk/nv/gfx/animation.hh	(revision 418)
+++ trunk/nv/gfx/animation.hh	(revision 419)
@@ -20,52 +20,46 @@
 {
 
-	class key_channel_set : public data_channel_set
+	class raw_channel_interpolator
 	{
 	public:
-		mat4 get_raw_matrix( uint32 index ) const 
-		{
-			float key[ 16 ];
+		explicit raw_channel_interpolator( const data_channel_set* set )
+			: m_set( set ), m_interpolation_key( set->get_interpolation_key() )
+		{
+		}
+		raw_channel_interpolator( const data_channel_set* set, const data_descriptor& ikey )
+			: m_set( set ), m_interpolation_key( ikey )
+		{ }
+
+		template < typename T >
+		T get_raw( uint32 index ) const
+		{
+			float key[16];
 			float* pkey = key;
-			for ( uint16 i = 0; i < size(); ++i )
-			{
-				pkey += get_raw( m_channels[i], index, pkey );
-			}
-			return extract_matrix_raw( m_final_key, key );
-		}
-
-		transform get_raw_transform( uint32 index ) const 
-		{
-			float key[ 16 ];
+			for ( const auto& channel : *m_set )
+			{
+				pkey += get_raw( channel, index, pkey );
+			}
+			return extract_key_raw< T >( m_interpolation_key, key );
+		}
+
+		template < typename T >
+		T get( float time ) const
+		{
+			float key[16];
 			float* pkey = key;
-			for ( uint16 i = 0; i < size(); ++i )
-			{
-				pkey += get_raw( m_channels[i], index, pkey );
-			}
-			return extract_transform_raw( m_final_key, key );
-		}
-
-		mat4 get_matrix( float time ) const
-		{
-			float key[ 16 ];
-			float* pkey = key;
-			for ( uint16 i = 0; i < size(); ++i )
-			{
-				pkey += interpolate_raw( m_channels[i], time, pkey );
-			}
-			return extract_matrix_raw( m_final_key, key );
-		}
-
-		transform get_transform( float time ) const
-		{
-			float key[ 16 ];
-			float* pkey = key;
-			for ( uint16 i = 0; i < size(); ++i )
-			{
-				pkey += interpolate_raw( m_channels[i], time, pkey );
-			}
-			return extract_transform_raw( m_final_key, key );
-		}
-
-		const data_descriptor& get_final_key() const { return m_final_key; }
+			for ( const auto& channel : *m_set )
+			{
+				pkey += interpolate_raw( channel, time, pkey );
+			}
+			return extract_key_raw< T >( m_interpolation_key, key );
+		}
+
+		template < typename T >
+		T  get( uint32 index1, uint32 index2, float interpolation ) const
+		{
+			T t1 = get_raw< T >( index1 );
+			T t2 = get_raw< T >( index2 );
+			return interpolate( t1, t2, interpolation );
+		}
 
 		static uint32 get_raw( const raw_data_channel& channel, uint32 index, float* result )
@@ -138,91 +132,88 @@
 			return ret;
 		}
-
-	private:
-		friend class key_channel_set_creator;
-
-		key_channel_set() {}
-
-		data_descriptor m_final_key;
+		const data_descriptor& get_interpolation_key() { return m_interpolation_key; }
+	protected:
+		const data_channel_set* m_set;
+		data_descriptor m_interpolation_key;
 	};
 
-	template < typename KEY, bool TIMED >
-	class key_channel_interpolator;
-
-
- 	template < typename KEY >
-	class key_channel_interpolator< KEY, false >
-	{
-	public:
-		key_channel_interpolator() : m_data( nullptr ) {}
-		key_channel_interpolator( const raw_data_channel* data ) : m_data( nullptr ) { set_data( data ); }
-		key_channel_interpolator( const raw_data_channel* data, bool ) : m_data( data ) {}
-		void set_data( const raw_data_channel* data )
-		{
-			m_data = data;
-			data_descriptor desc;
-			desc.initialize<KEY>();
-			NV_ASSERT( data->descriptor() == desc, "Bad channel passed!" );
-		}
-		void get_interpolated( KEY& result, float frame ) const
-		{
-			NV_ASSERT( m_data, "Data is null!" );
-			const KEY* keys = m_data->data_cast<KEY>( );
-			uint32 count = m_data->size();
-			if ( count == 0 ) return;
-			if ( count == 1 )
-			{
-				result = keys[0];
-				return;
-			}
-			size_t index = glm::clamp<size_t>( size_t( frame ), 0, count - 2 );
-			float factor = glm::clamp<float> ( frame - index, 0.0f, 1.0f );
-			interpolate_key( result, keys[index], keys[index+1], factor );
-		}
-
-	private:
-		const raw_data_channel* m_data;
-	};
- 
- 	template < typename KEY >
- 	class key_channel_interpolator< KEY, true >
-	{
-	public:
-		key_channel_interpolator() : m_data( nullptr ) {}
-		key_channel_interpolator( const raw_data_channel* data ) : m_data( nullptr ) { set_data( data ); }
-		void set_data( const raw_data_channel* data )
-		{
-			m_data = data;
-			data_descriptor desc;
-			desc.initialize<KEY>();
-			NV_ASSERT( data->descriptor() == desc, "Bad channel passed!" );
-		}
-		void get_interpolated( KEY& result, float time ) const
-		{
-			// TODO: this probably could be optimized
-			NV_ASSERT( m_data, "Data is null!" );
-			const KEY* keys = m_data->data_cast<KEY>( );
-			uint32 count = m_data->size();
-			if ( count == 0 ) return;
-			if ( count == 1 ) 
-			{
-				result = keys[0];
-				return;
-			}
-			int index = -1;
-			for ( int i = 0 ; i < int( count ) - 1 ; i++ )
-			{
-				if ( time < keys[i + 1].time ) { index = i; break; }
-			}
-			NV_ASSERT( index >= 0, "animation time fail!");
-			float delta  = keys[index + 1].time - keys[index].time;
-			float factor = glm::clamp( (time - keys[index].time) / delta, 0.0f, 1.0f );
-			interpolate_key( result, keys[index], keys[index+1], factor );
-		}
-
-	private:
-		const raw_data_channel* m_data;
-	};
- 
+// 	template < typename KEY, bool TIMED >
+// 	class key_channel_interpolator;
+// 
+// 
+//  	template < typename KEY >
+// 	class key_channel_interpolator< KEY, false >
+// 	{
+// 	public:
+// 		key_channel_interpolator() : m_data( nullptr ) {}
+// 		key_channel_interpolator( const raw_data_channel* data ) : m_data( nullptr ) { set_data( data ); }
+// 		key_channel_interpolator( const raw_data_channel* data, bool ) : m_data( data ) {}
+// 		void set_data( const raw_data_channel* data )
+// 		{
+// 			m_data = data;
+// 			data_descriptor desc;
+// 			desc.initialize<KEY>();
+// 			NV_ASSERT( data->descriptor() == desc, "Bad channel passed!" );
+// 		}
+// 		void get_interpolated( KEY& result, float frame ) const
+// 		{
+// 			NV_ASSERT( m_data, "Data is null!" );
+// 			const KEY* keys = m_data->data_cast<KEY>( );
+// 			uint32 count = m_data->size();
+// 			if ( count == 0 ) return;
+// 			if ( count == 1 )
+// 			{
+// 				result = keys[0];
+// 				return;
+// 			}
+// 			size_t index = glm::clamp<size_t>( size_t( frame ), 0, count - 2 );
+// 			float factor = glm::clamp<float> ( frame - index, 0.0f, 1.0f );
+// 			interpolate_key( result, keys[index], keys[index+1], factor );
+// 		}
+// 
+// 	private:
+// 		const raw_data_channel* m_data;
+// 	};
+//  
+//  	template < typename KEY >
+//  	class key_channel_interpolator< KEY, true >
+// 	{
+// 	public:
+// 		key_channel_interpolator() : m_data( nullptr ) {}
+// 		key_channel_interpolator( const raw_data_channel* data ) : m_data( nullptr ) { set_data( data ); }
+// 		void set_data( const raw_data_channel* data )
+// 		{
+// 			m_data = data;
+// 			data_descriptor desc;
+// 			desc.initialize<KEY>();
+// 			NV_ASSERT( data->descriptor() == desc, "Bad channel passed!" );
+// 		}
+// 		void get_interpolated( KEY& result, float time ) const
+// 		{
+// 			// TODO: this probably could be optimized
+// 			NV_ASSERT( m_data, "Data is null!" );
+// 			const KEY* keys = m_data->data_cast<KEY>( );
+// 			uint32 count = m_data->size();
+// 			if ( count == 0 ) return;
+// 			if ( count == 1 ) 
+// 			{
+// 				result = keys[0];
+// 				return;
+// 			}
+// 			int index = -1;
+// 			for ( int i = 0 ; i < int( count ) - 1 ; i++ )
+// 			{
+// 				if ( time < keys[i + 1].time ) { index = i; break; }
+// 			}
+// 			NV_ASSERT( index >= 0, "animation time fail!");
+// 			float delta  = keys[index + 1].time - keys[index].time;
+// 			float factor = glm::clamp( (time - keys[index].time) / delta, 0.0f, 1.0f );
+// 			interpolate_key( result, keys[index], keys[index+1], factor );
+// 		}
+// 
+// 	private:
+// 		const raw_data_channel* m_data;
+// 	};
+//  
 // 	template < typename KEY1, typename KEY2 = void, typename KEY3 = void >
 // 	class key_data_interpolator
@@ -230,122 +221,60 @@
 // 
 // 	};
-
-	class key_animation_data
-	{
-	public:
-		virtual mat4 get_matrix( float time ) const = 0;
-		virtual transform get_transform( float time ) const = 0;
-		virtual bool empty() const = 0;
-		virtual size_t size() const = 0;
-		virtual uint32 raw_size() const = 0;
-		virtual ~key_animation_data() {}
-	};
-
-
-	class key_vectors_prs : public key_animation_data
-	{
-		struct key_p { float time; vec3 position; };
-		struct key_r { float time; quat rotation; };
-		struct key_s { float time; vec3 scale; };
-	public:
-		explicit key_vectors_prs( const raw_data_channel* p, const raw_data_channel* r, const raw_data_channel* s )
-		{
-			m_pchannel = p;
-			m_rchannel = r;
-			m_schannel = s;
-			m_pinter.set_data( m_pchannel );
-			m_rinter.set_data( m_rchannel );
-			m_sinter.set_data( m_schannel );
-		}
-		size_t size() const { return 0; } // TODO: remove?
-		bool empty() const { 
-			return m_pchannel->size() == 0
-				&& m_rchannel->size() == 0
-				&& m_schannel->size() == 0; }
-		virtual mat4 get_matrix( float time ) const
-		{
-			key_p p;
-			key_r r;
-			key_s s;
-
-			m_pinter.get_interpolated( p, time );
-			m_rinter.get_interpolated( r, time );
-			m_sinter.get_interpolated( s, time );
-
-			return extract_matrix( p ) * extract_matrix( r ) * extract_matrix( s );
-		}
-		virtual transform get_transform( float time ) const
-		{
-			key_p p;
-			key_r r;
-
-			m_pinter.get_interpolated( p, time );
-			m_rinter.get_interpolated( r, time );
-
-			return transform( p.position, r.rotation );
-		}
-		virtual uint32 raw_size() const 
-		{
-			return 3 * sizeof( size_t ) 
-				+ m_pchannel->size() * sizeof( key_p )
-				+ m_rchannel->size() * sizeof( key_r )
-				+ m_schannel->size() * sizeof( key_s );
-		}
-		~key_vectors_prs()
-		{
-		}
-	protected:
-		const raw_data_channel* m_pchannel;
-		const raw_data_channel* m_rchannel;
-		const raw_data_channel* m_schannel;
-		key_channel_interpolator< key_p, true > m_pinter;
-		key_channel_interpolator< key_r, true > m_rinter;
-		key_channel_interpolator< key_s, true > m_sinter;
-	};
-
-	class transform_vector : public key_animation_data
-	{
-		struct key
-		{
-			transform tform;
-		};
-	public:
-		explicit transform_vector( const raw_data_channel* channel )
-		{
-			data_descriptor kd;
-			kd.initialize<key>();
-			NV_ASSERT( kd == channel->descriptor(), "bad channel!" );
-			m_channel = channel;
-			m_interpolator.set_data( m_channel );
-		}
-
-		~transform_vector()
-		{
-			delete m_channel;
-		}
-		bool empty() const { return m_channel->size() == 0; }
-		size_t size() const { return m_channel->size(); }
-		const transform& get( size_t index ) const { return m_channel->data_cast< key >()[ index ].tform; }
-		const transform* data() const { return &(m_channel->data_cast< key >()[0].tform); }
-
-		virtual uint32 raw_size() const 
-		{
-			return sizeof( size_t ) + m_channel->size() * sizeof( key );
-		}
-
-		virtual mat4 get_matrix( float time ) const
-		{
-			return get_transform( time ).extract();
-		}
-		virtual transform get_transform( float time ) const
-		{
-			key result;
-			m_interpolator.get_interpolated( result, time );
-			return extract_transform< key >( result );
-		}
-	protected:
-		key_channel_interpolator< key, false > m_interpolator;
-		const raw_data_channel* m_channel;
-	};
+// 
+// 	class key_animation_data
+// 	{
+// 	public:
+// 		virtual mat4 get_matrix( float time ) const = 0;
+// 		virtual transform get_transform( float time ) const = 0;
+// 		virtual bool empty() const = 0;
+// 		virtual size_t size() const = 0;
+// 		virtual uint32 raw_size() const = 0;
+// 		virtual ~key_animation_data() {}
+// 	};
+
+// 	class transform_vector : public key_animation_data
+// 	{
+// 		struct key
+// 		{
+// 			transform tform;
+// 		};
+// 	public:
+// 		explicit transform_vector( const raw_data_channel* channel )
+// 		{
+// 			data_descriptor kd;
+// 			kd.initialize<key>();
+// 			NV_ASSERT( kd == channel->descriptor(), "bad channel!" );
+// 			m_channel = channel;
+// 			m_interpolator.set_data( m_channel );
+// 		}
+// 
+// 		~transform_vector()
+// 		{
+// 			delete m_channel;
+// 		}
+// 		bool empty() const { return m_channel->size() == 0; }
+// 		size_t size() const { return m_channel->size(); }
+// 		const transform& get( size_t index ) const { return m_channel->data_cast< key >()[ index ].tform; }
+// 		const transform* data() const { return &(m_channel->data_cast< key >()[0].tform); }
+// 
+// 		virtual uint32 raw_size() const 
+// 		{
+// 			return sizeof( size_t ) + m_channel->size() * sizeof( key );
+// 		}
+// 
+// 		virtual mat4 get_matrix( float time ) const
+// 		{
+// 			return get_transform( time ).extract();
+// 		}
+// 		virtual transform get_transform( float time ) const
+// 		{
+// 			key result;
+// 			m_interpolator.get_interpolated( result, time );
+// 			return extract_transform< key >( result );
+// 		}
+// 	protected:
+// 		key_channel_interpolator< key, false > m_interpolator;
+// 		const raw_data_channel* m_channel;
+// 	};
 
 
