common/animation/offline/animation_builder.cc
// Ensures _input's validity and allocates _animation.
// An animation needs to have at least two key frames per joint, the first at
// t = 0 and the last at t = duration. If at least one of those keys are not
// in the RawAnimation then the builder creates it.

Ensures _input's validity and allocates _animation.
An animation needs to have at least two key frames per joint, the first at
t = 0 and the last at t = duration. If at least one of those keys are not
in the RawAnimation then the builder creates it.
Ensures _input ' s validity and allocates _animation . An animation needs to have at least two key frames per joint the first at t = 0 and the last at t = duration . If at least one of those keys are not in the RawAnimation then the builder creates it .
Animation* AnimationBuilder::operator()(const RawAnimation& _input) const
			{
				if (!_input.Validate())
				{
					return NULL;
				}
				Animation* animation = (Animation*)g_allocator->allocate(sizeof(Animation));
				const float duration = _input.duration;
				animation->duration_ = duration;
				assert(duration > 0.f);  
				const uint16_t num_tracks = static_cast<uint16_t>(_input.num_tracks());
				animation->num_tracks_ = num_tracks;
				const uint16_t num_soa_tracks = math::Align(num_tracks, 4);
				size_t translations = 0, rotations = 0, scales = 0;
				for (int i = 0; i < num_tracks; ++i)
				{
					const RawAnimation::JointTrack& raw_track = _input.tracks[i];
					translations += raw_track.translations.size() + 2;  
					rotations += raw_track.rotations.size() + 2;        
					scales += raw_track.scales.size() + 2;              
				}
				std::vector<SortingTranslationKey> sorting_translations;
				sorting_translations.reserve(translations);
				std::vector<SortingRotationKey> sorting_rotations;
				sorting_rotations.reserve(rotations);
				std::vector<SortingScaleKey> sorting_scales;
				sorting_scales.reserve(scales);
				uint16_t i = 0;
				for (; i < num_tracks; ++i)
				{
					const RawAnimation::JointTrack& raw_track = _input.tracks[i];
					CopyRaw(raw_track.translations, i, duration, &sorting_translations);
					CopyRaw(raw_track.rotations, i, duration, &sorting_rotations);
					CopyRaw(raw_track.scales, i, duration, &sorting_scales);
				}
				for (; i < num_soa_tracks; ++i)
				{
					typedef RawAnimation::TranslationKey SrcTKey;
					PushBackIdentityKey<SrcTKey>(i, 0.f, &sorting_translations);
					PushBackIdentityKey<SrcTKey>(i, duration, &sorting_translations);
					typedef RawAnimation::RotationKey SrcRKey;
					PushBackIdentityKey<SrcRKey>(i, 0.f, &sorting_rotations);
					PushBackIdentityKey<SrcRKey>(i, duration, &sorting_rotations);
					typedef RawAnimation::ScaleKey SrcSKey;
					PushBackIdentityKey<SrcSKey>(i, 0.f, &sorting_scales);
					PushBackIdentityKey<SrcSKey>(i, duration, &sorting_scales);
				}
				animation->Allocate(_input.name.length() + 1, sorting_translations.size(),
					sorting_rotations.size(), sorting_scales.size());
				CopyToAnimation(&sorting_translations, &animation->translations_);
				CopyToAnimation(&sorting_rotations, &animation->rotations_);
				CopyToAnimation(&sorting_scales, &animation->scales_);
				strcpy(animation->name_, _input.name.c_str());
				return animation;  
			}
Animation * AnimationBuilder :: operator () ( const RawAnimation & _input ) const { if ( ! _input . Validate ( ) ) { return NULL ; } Animation * animation = ( Animation * ) g_allocator -> allocate ( sizeof ( Animation ) ) ; const float duration = _input . duration ; animation -> duration_ = duration ; assert ( duration > 0.f ) ; const uint16_t num_tracks = static_cast < uint16_t > ( _input . num_tracks ( ) ) ; animation -> num_tracks_ = num_tracks ; const uint16_t num_soa_tracks = math :: Align ( num_tracks , 4 ) ; size_t translations = 0 , rotations = 0 , scales = 0 ; for ( int i = 0 ; i < num_tracks ; ++ i ) { const RawAnimation :: JointTrack & raw_track = _input . tracks [ i ] ; translations += raw_track . translations . size ( ) + 2 ; rotations += raw_track . rotations . size ( ) + 2 ; scales += raw_track . scales . size ( ) + 2 ; } std :: vector < SortingTranslationKey > sorting_translations ; sorting_translations . reserve ( translations ) ; std :: vector < SortingRotationKey > sorting_rotations ; sorting_rotations . reserve ( rotations ) ; std :: vector < SortingScaleKey > sorting_scales ; sorting_scales . reserve ( scales ) ; uint16_t i = 0 ; for ( ; i < num_tracks ; ++ i ) { const RawAnimation :: JointTrack & raw_track = _input . tracks [ i ] ; CopyRaw ( raw_track . translations , i , duration , & sorting_translations ) ; CopyRaw ( raw_track . rotations , i , duration , & sorting_rotations ) ; CopyRaw ( raw_track . scales , i , duration , & sorting_scales ) ; } for ( ; i < num_soa_tracks ; ++ i ) { typedef RawAnimation :: TranslationKey SrcTKey ; PushBackIdentityKey < SrcTKey > ( i , 0.f , & sorting_translations ) ; PushBackIdentityKey < SrcTKey > ( i , duration , & sorting_translations ) ; typedef RawAnimation :: RotationKey SrcRKey ; PushBackIdentityKey < SrcRKey > ( i , 0.f , & sorting_rotations ) ; PushBackIdentityKey < SrcRKey > ( i , duration , & sorting_rotations ) ; typedef RawAnimation :: ScaleKey SrcSKey ; PushBackIdentityKey < SrcSKey > ( i , 0.f , & sorting_scales ) ; PushBackIdentityKey < SrcSKey > ( i , duration , & sorting_scales ) ; } animation -> Allocate ( _input . name . length ( ) + 1 , sorting_translations . size ( ) , sorting_rotations . size ( ) , sorting_scales . size ( ) ) ; CopyToAnimation ( & sorting_translations , & animation -> translations_ ) ; CopyToAnimation ( & sorting_rotations , & animation -> rotations_ ) ; CopyToAnimation ( & sorting_scales , & animation -> scales_ ) ; strcpy ( animation -> name_ , _input . name . c_str ( ) ) ; return animation ; }
Ensures _input's validity and allocates _animation.
Ensures _input ' s validity and allocates _animation .
// Tests _raw_animation validity.
 // Everything is fine, allocates and fills the animation.
 // Nothing can fail now.
 // Sets duration.
 // A _duration == 0 would create some division by 0 during sampling.
 // Also we need at least to keys with different times, which cannot be done
 // if duration is 0.
 // This case is handled by Validate().
 // Sets tracks count. Can be safely casted to uint16_t as number of tracks as
 // already been validated.
 // Declares and preallocates tracks to sort.
 // +2 because worst case
 // needs to add the
 // first and last keys.
 // Filters RawAnimation keys and copies them to the output sorting structure.
 // Add enough identity keys to match soa requirements.
 // Allocate animation members.
 // Copy sorted keys to final animation.
 // Copy animation's name.
 // Success.
