载入中...
搜索中...
未找到
AnimConstraintStack.cpp
浏览该文件的文档.
2
5#include "common/Exception.h"
6
7#include <cmath>
8
9namespace eve::animation {
10
12 if (!skeleton_) throw Exception("AnimConstraintStack: skeleton is null");
13}
14
16 if (skeleton_ == skeleton) return;
17 skeleton_ = skeleton;
18 clear();
19}
20
21void AnimConstraintStack::addAim(int bone, float targetX, float targetY, float targetZ, float weight) {
22 constraints_.push_back({Type::Aim, bone, -1, -1, targetX, targetY, targetZ, 0.f, 1.f, 0.f, 0.f,
23 clampf(weight, 0.f, 1.f)});
24}
25
26void AnimConstraintStack::addTwoBoneIK(int root, int mid, int tip, float targetX, float targetY, float targetZ,
27 float weight) {
28 constraints_.push_back({Type::TwoBone, root, mid, tip, targetX, targetY, targetZ, 0.f, 1.f, 0.f, 0.f,
29 clampf(weight, 0.f, 1.f)});
30}
31
32void AnimConstraintStack::addFootIK(int hip, int knee, int foot, float groundY, float normalX, float normalY,
33 float normalZ, float soleOffset, float weight) {
34 const float length = std::sqrt(normalX * normalX + normalY * normalY + normalZ * normalZ);
35 if (length < 1e-6f) throw Exception("AnimConstraintStack.addFootIK: ground normal is zero");
36 constraints_.push_back({Type::Foot, hip, knee, foot, 0.f, groundY, 0.f, normalX / length, normalY / length,
37 normalZ / length, soleOffset, clampf(weight, 0.f, 1.f)});
38}
39
41 if (!pose) throw Exception("AnimConstraintStack.apply: pose is null");
42 if (!skeleton_) throw Exception("AnimConstraintStack.apply: skeleton is null");
43 pose->computeWorld(skeleton_);
44 for (const Constraint& constraint : constraints_) {
45 if (constraint.type == Type::Aim) {
46 pose->aimBone(skeleton_, constraint.a, constraint.x, constraint.y, constraint.z, constraint.weight);
47 } else if (constraint.type == Type::TwoBone) {
48 pose->solveTwoBoneIK(skeleton_, constraint.a, constraint.b, constraint.c, constraint.x, constraint.y,
49 constraint.z, constraint.weight);
50 } else {
51 pose->computeWorld(skeleton_);
52 const TransformTRS& foot = pose->world(constraint.c);
53 const float targetY = constraint.y + constraint.offset;
54 pose->solveTwoBoneIK(skeleton_, constraint.a, constraint.b, constraint.c, foot.px, targetY, foot.pz,
55 constraint.weight);
56 pose->computeWorld(skeleton_);
57 const TransformTRS& planted = pose->world(constraint.c);
58 pose->aimBone(skeleton_, constraint.c, planted.px + constraint.nx, planted.py + constraint.ny,
59 planted.pz + constraint.nz, constraint.weight);
60 }
61 }
62 pose->computeWorld(skeleton_);
63}
64
65} // namespace eve::animation
int tip
Definition AnimSmr.cpp:121
int root
Definition AnimSmr.cpp:119
int mid
Definition AnimSmr.cpp:120
eve::EntitySpatialPose pose
float length
Definition CaveMesh.cpp:94
std::uint32_t bone
float targetX
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
void setSkeleton(AnimSkeleton *skeleton)
Rebind the borrowed skeleton; changing it clears old index constraints.
AnimConstraintStack(AnimSkeleton *skeleton)
Construct for a non-null borrowed skeleton.
void addAim(int bone, float targetX, float targetY, float targetZ, float weight=1.f)
Append a weighted bone aim constraint.
void clear()
Remove all constraints.
void addFootIK(int hip, int knee, int foot, float groundY, float normalX=0.f, float normalY=1.f, float normalZ=0.f, float soleOffset=0.f, float weight=1.f)
Plant a foot at groundY + soleOffset and orient its local +Z toward the ground normal.
void apply(AnimPose *pose) const
Apply constraints in insertion order and refresh world transforms. Main-thread only.
void addTwoBoneIK(int root, int mid, int tip, float targetX, float targetY, float targetZ, float weight=1.f)
Append a weighted two-bone IK constraint.
Evaluated local (and optional world) pose for an AnimSkeleton. Script type: AnimPose.
Definition AnimPose.h:17
3D bone hierarchy + bind-pose local TRS for skeletal animation. Independent of ik::Skeleton3D (FABRIK...
float clampf(float v, float lo, float hi)
Clampf.
Definition AnimMath.h:34
Local TRS used by skeletal animation (quaternion xyzw).
Definition AnimMath.h:9