载入中...
搜索中...
未找到
MotionMatcherLocomotion.cpp
浏览该文件的文档.
1#include <algorithm>
2#include <cmath>
6#include "common/Exception.h"
7
8namespace eve::animation {
10 float elapsedSeconds,
11 std::span<const MotionLocomotionSample> samples) {
12 auto finitePose = [](const AnimPose& pose) {
13 for (int i = 0; i < pose.getBoneCount(); ++i) {
14 const auto& t = pose.local(i);
15 for (float v : {t.px, t.py, t.pz, t.qx, t.qy, t.qz, t.qw, t.sx, t.sy, t.sz})
16 if (!std::isfinite(v)) return false;
17 }
18 return true;
19 };
20 if (!database_->hasLocomotionFeatures() || current.getBoneCount() != pose_.getBoneCount() ||
21 previous.getBoneCount() != pose_.getBoneCount() || !std::isfinite(elapsedSeconds) || elapsedSeconds <= 0.f ||
22 elapsedSeconds > 1.f || samples.size() != 5 || !finitePose(current) || !finitePose(previous) ||
23 std::any_of(samples.begin(), samples.end(), [](const auto& s) {
24 for (float v : {s.x, s.y, s.z, s.vx, s.vy, s.vz, s.yaw})
25 if (!std::isfinite(v)) return true;
26 return false;
27 }))
30 "locomotion query requires the locomotion layout, finite matching poses, five samples, and dt in (0,1]",
31 "locomotionQuery", {}, "animation"));
32 AnimPose nextCurrent, nextPrevious;
33 nextCurrent.copyFrom(&current);
34 nextPrevious.copyFrom(&previous);
35 queryPose_ = std::move(nextCurrent);
36 previousQueryPose_ = std::move(nextPrevious);
37 std::copy(samples.begin(), samples.end(), locomotionTrajectory_.begin());
38 queryPoseInterval_ = elapsedSeconds;
39 hasLocomotionQuery_ = true;
40 hasQueryPose_ = true;
42}
43
44void MotionMatcher::buildLocomotionQuery(std::vector<float>& query) const {
45 if (!hasLocomotionQuery_) throw Exception("MotionMatcher: configure a locomotion query before searching");
46 query.assign(detail::locomotionFeatureCount, 0.f);
47 detail::encodeLocomotionTrajectory(std::span(query), locomotionTrajectory_, desiredYaw_);
48 AnimPose current, previous;
49 current.copyFrom(&queryPose_);
50 previous.copyFrom(&previousQueryPose_);
51 current.computeWorld(skeleton_);
52 previous.computeWorld(skeleton_);
53 std::array<TransformTRS, 4> now{}, past{};
54 now[0] = current.world(database_->getRootBone());
55 past[0] = previous.world(database_->getRootBone());
56 for (int i = 0; i < 3; ++i) {
57 const int bone = database_->getFeatureBone(i);
58 now[i + 1] = current.world(bone);
59 past[i + 1] = previous.world(bone);
60 }
61 detail::encodeLocomotionPose(query, now, past, queryPoseInterval_);
62 database_->normalizeFeature(query);
63}
64} // namespace eve::animation
eve::EntitySpatialPose pose
const std::string & s
float v
std::uint32_t bone
graphics::Canvas * previous
float t
double current
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
Evaluated local (and optional world) pose for an AnimSkeleton. Script type: AnimPose.
Definition AnimPose.h:17
int getBoneCount() const
Returns the bone count.
Definition AnimPose.h:36
bool hasLocomotionFeatures() const
Whether this database uses the 30-dimensional locomotion layout.
eve::Result< void > setLocomotionQuery(const AnimPose &current, const AnimPose &previous, float elapsedSeconds, std::span< const MotionLocomotionSample > samples)
Atomically copy pose history and trajectory for a locomotion database.