/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2022 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ namespace openspace { template Keyframe::Keyframe(size_t i, double t, T d) : KeyframeBase{ i, t } , data(std::move(d)) {} template void Timeline::addKeyframe(double timestamp, T&& data) { Keyframe keyframe(++_nextKeyframeId, timestamp, std::move(data)); const auto iter = std::upper_bound( _keyframes.cbegin(), _keyframes.cend(), keyframe, &compareKeyframeTimes ); _keyframes.insert(iter, std::move(keyframe)); } template void Timeline::addKeyframe(double timestamp, const T& data) { Keyframe keyframe(++_nextKeyframeId, timestamp, data); const auto iter = std::upper_bound( _keyframes.cbegin(), _keyframes.cend(), keyframe, &compareKeyframeTimes ); _keyframes.insert(iter, std::move(keyframe)); } template void Timeline::removeKeyframesAfter(double timestamp, bool inclusive) { typename std::deque>::const_iterator iter; if (inclusive) { iter = std::lower_bound( _keyframes.cbegin(), _keyframes.cend(), timestamp, &compareKeyframeTimeWithTime ); } else { iter = std::upper_bound( _keyframes.cbegin(), _keyframes.cend(), timestamp, &compareTimeWithKeyframeTime ); } _keyframes.erase(iter, _keyframes.end()); } template void Timeline::removeKeyframesBefore(double timestamp, bool inclusive) { typename std::deque>::const_iterator iter; if (inclusive) { iter = std::upper_bound( _keyframes.cbegin(), _keyframes.cend(), timestamp, &compareTimeWithKeyframeTime ); } else { iter = std::lower_bound( _keyframes.cbegin(), _keyframes.cend(), timestamp, &compareKeyframeTimeWithTime ); } _keyframes.erase(_keyframes.begin(), iter); } template void Timeline::removeKeyframesBetween(double begin, double end, bool inclusiveBegin, bool inclusiveEnd) { typename std::deque>::const_iterator beginIter; if (inclusiveBegin) { beginIter = std::lower_bound( _keyframes.cbegin(), _keyframes.cend(), begin, &compareKeyframeTimeWithTime ); } else { beginIter = std::upper_bound( _keyframes.cbegin(), _keyframes.cend(), begin, &compareTimeWithKeyframeTime ); } typename std::deque>::const_iterator endIter; if (inclusiveEnd) { endIter = std::upper_bound( beginIter, _keyframes.cend(), end, &compareTimeWithKeyframeTime ); } else { endIter = std::lower_bound( beginIter, _keyframes.cend(), end, &compareKeyframeTimeWithTime ); } _keyframes.erase(beginIter, endIter); } template void Timeline::clearKeyframes() { _keyframes.clear(); } template void Timeline::removeKeyframe(size_t id) { _keyframes.erase( std::remove_if( _keyframes.begin(), _keyframes.end(), [id] (const Keyframe& keyframe) { return keyframe.id == id; } ), _keyframes.end() ); } template size_t Timeline::nKeyframes() const { return _keyframes.size(); } template const Keyframe* Timeline::firstKeyframeAfter(double timestamp, bool inclusive) const { typename std::deque>::const_iterator it; if (inclusive) { it = std::lower_bound( _keyframes.begin(), _keyframes.end(), timestamp, &compareKeyframeTimeWithTime ); } else { it = std::upper_bound( _keyframes.begin(), _keyframes.end(), timestamp, &compareTimeWithKeyframeTime ); } if (it == _keyframes.end()) { return nullptr; } return &(*it); } template const Keyframe* Timeline::lastKeyframeBefore(double timestamp, bool inclusive) const { typename std::deque>::const_iterator it; if (inclusive) { it = std::upper_bound( _keyframes.begin(), _keyframes.end(), timestamp, &compareTimeWithKeyframeTime ); } else { it = std::lower_bound( _keyframes.begin(), _keyframes.end(), timestamp, &compareKeyframeTimeWithTime ); } if (it == _keyframes.begin()) { return nullptr; } it--; return &(*it); } template const std::deque>& Timeline::keyframes() const { return _keyframes; } } // namespace openspace