| 100 | // in the RawAnimation then the builder creates it. |
| 101 | template <typename _RawTrack, typename _Track> |
| 102 | unique_ptr<_Track> TrackBuilder::Build(const _RawTrack& _input) const { |
| 103 | // Tests _raw_animation validity. |
| 104 | if (!_input.Validate()) { |
| 105 | return unique_ptr<_Track>(); |
| 106 | } |
| 107 | |
| 108 | // Everything is fine, allocates and fills the animation. |
| 109 | // Nothing can fail now. |
| 110 | unique_ptr<_Track> track = make_unique<_Track>(); |
| 111 | |
| 112 | // Copy data to temporary prepared data structure |
| 113 | typename _RawTrack::Keyframes keyframes; |
| 114 | // Guessing a worst size to avoid realloc. |
| 115 | const size_t worst_size = |
| 116 | _input.keyframes.size() * 2 + // * 2 in case all keys are kStep |
| 117 | 2; // + 2 for first and last keys |
| 118 | keyframes.reserve(worst_size); |
| 119 | |
| 120 | // Ensure there's a key frame at the start and end of the track (required for |
| 121 | // sampling). |
| 122 | PatchBeginEndKeys(_input, &keyframes); |
| 123 | |
| 124 | // Fixup values, ex: successive opposite quaternions that would fail to take |
| 125 | // the shortest path during the normalized-lerp. |
| 126 | Fixup(&keyframes); |
| 127 | |
| 128 | // Allocates output track. |
| 129 | const size_t name_len = _input.name.size(); |
| 130 | track->Allocate(keyframes.size(), _input.name.size()); |
| 131 | |
| 132 | // Copy all keys to output. |
| 133 | SKR_ASSERT(keyframes.size() == track->ratios_.size() && |
| 134 | keyframes.size() == track->values_.size() && |
| 135 | keyframes.size() <= track->steps_.size() * 8); |
| 136 | memset(track->steps_.data(), 0, track->steps_.size_bytes()); |
| 137 | for (size_t i = 0; i < keyframes.size(); ++i) { |
| 138 | const typename _RawTrack::Keyframe& src_key = keyframes[i]; |
| 139 | track->ratios_[i] = src_key.ratio; |
| 140 | track->values_[i] = src_key.value; |
| 141 | track->steps_[i / 8] |= |
| 142 | (src_key.interpolation == RawTrackInterpolation::kStep) << (i & 7); |
| 143 | } |
| 144 | |
| 145 | // Copy track's name. |
| 146 | if (name_len) { |
| 147 | strcpy(track->name_, _input.name.c_str()); |
| 148 | } |
| 149 | |
| 150 | return track; // Success. |
| 151 | } |
| 152 | |
| 153 | unique_ptr<FloatTrack> TrackBuilder::operator()( |
| 154 | const RawFloatTrack& _input) const { |
no test coverage detected