Program Listing for File motion.impl.hpp¶
↰ Return to documentation for file (include/flom/motion.impl.hpp
)
//
// Copyright 2018 coord.e
//
// This file is part of Flom.
//
// Flom is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Flom is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flom. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef FLOM_MOTION_IMPL_HPP
#define FLOM_MOTION_IMPL_HPP
#include "flom/frame.hpp"
#include "flom/motion.hpp"
#include "motion.pb.h"
#include <functional>
#include <map>
#include <numeric>
#include <string>
#include <unordered_map>
#include <unordered_set>
namespace flom {
template <typename K> std::size_t names_hash(const std::unordered_set<K> &s) {
auto h{s.hash_function()};
return std::accumulate(std::cbegin(s), std::cend(s),
static_cast<std::size_t>(0),
[&h](auto r, const auto &p) { return r ^ h(p); });
}
template <typename K, typename V>
std::size_t names_hash(const std::unordered_map<K, V> &m) {
auto h{m.hash_function()};
return std::accumulate(
std::cbegin(m), std::cend(m), static_cast<std::size_t>(0),
[&h](auto r, const auto &p) { return r ^ h(p.first); });
}
class Motion::Impl {
public:
std::string model_id;
LoopType loop;
std::map<double, Frame> raw_frames;
// keys of these two member must not be changed after construction
const std::unordered_set<std::string> joint_names;
const std::unordered_map<std::string, EffectorType> effector_types;
std::unordered_map<std::string, EffectorWeight> effector_weights;
// Hash of joint_names
const std::size_t joints_hash;
// Hash of keys of effector_types
const std::size_t effectors_hash;
Impl(const std::unordered_set<std::string> &joints,
const std::unordered_map<std::string, EffectorType> &effectors,
const std::string &model = "")
: model_id(model), loop(LoopType::None), raw_frames(),
joint_names(joints), effector_types(effectors),
joints_hash(names_hash(joints)), effectors_hash(names_hash(effectors)) {
this->effector_weights.reserve(effectors.size());
for (const auto &[name, e] : effectors) {
this->effector_weights.emplace(name, EffectorWeight{0.0, 0.0});
}
this->add_initial_frame();
}
void add_initial_frame();
Frame new_keyframe() const noexcept;
static Motion from_protobuf(proto::Motion const &);
proto::Motion to_protobuf() const;
bool is_valid() const;
bool is_valid_frame(const Frame &) const;
};
} // namespace flom
#endif