载入中...
搜索中...
未找到
SpineSkeleton.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4
5#include <cmath>
6
7#ifndef M_PI
8#define M_PI 3.14159265358979323846
9#endif
10
11namespace eve::animation {
12
13namespace {
14float degToRad(float deg) { return deg * static_cast<float>(M_PI / 180.0); }
15} // namespace
16
18 if (!data_) throw Exception("SpineSkeleton: data is null");
19 bones_.resize(static_cast<size_t>(data_->getBoneCount()));
20 slotAttachments_.resize(static_cast<size_t>(data_->getSlotCount()));
21 skinIndex_ = data_->getDefaultSkin();
22 if (skinIndex_ < 0) skinIndex_ = 0;
25}
26
27void SpineSkeleton::checkBone(int index) const {
28 if (index < 0 || index >= getBoneCount())
29 throw Exception("SpineSkeleton: bone index %d out of range", index);
30}
31void SpineSkeleton::checkSlot(int index) const {
32 if (index < 0 || index >= getSlotCount())
33 throw Exception("SpineSkeleton: slot index %d out of range", index);
34}
35
36int SpineSkeleton::getBoneCount() const { return static_cast<int>(bones_.size()); }
37int SpineSkeleton::getSlotCount() const { return static_cast<int>(slotAttachments_.size()); }
38
39bool SpineSkeleton::setSkin(const std::string &name) {
40 int idx = data_->findSkin(name);
41 if (idx < 0) return false;
42 skinIndex_ = idx;
43 return true;
44}
45
47 for (int i = 0; i < data_->getBoneCount(); ++i) {
48 const auto &b = data_->bone(i);
49 BonePose &p = bones_[static_cast<size_t>(i)];
50 p.x = b.x;
51 p.y = b.y;
52 p.rotation = b.rotation;
53 p.scaleX = b.scaleX;
54 p.scaleY = b.scaleY;
55 }
56 for (int i = 0; i < data_->getSlotCount(); ++i)
57 slotAttachments_[static_cast<size_t>(i)] = data_->slot(i).attachment;
58}
59
61 for (int i = 0; i < getBoneCount(); ++i) {
62 BonePose &p = bones_[static_cast<size_t>(i)];
63 const int parent = data_->bone(i).parent;
64 const float rad = degToRad(p.rotation);
65 const float cos = std::cos(rad);
66 const float sin = std::sin(rad);
67 const float la = cos * p.scaleX;
68 const float lb = -sin * p.scaleY;
69 const float lc = sin * p.scaleX;
70 const float ld = cos * p.scaleY;
71
72 if (parent < 0) {
73 p.a = la;
74 p.b = lb;
75 p.c = lc;
76 p.d = ld;
77 p.worldX = p.x;
78 p.worldY = p.y;
79 p.worldRot = p.rotation;
80 p.worldSX = p.scaleX;
81 p.worldSY = p.scaleY;
82 } else {
83 const BonePose &pp = bones_[static_cast<size_t>(parent)];
84 p.worldX = pp.a * p.x + pp.b * p.y + pp.worldX;
85 p.worldY = pp.c * p.x + pp.d * p.y + pp.worldY;
86 p.a = pp.a * la + pp.b * lc;
87 p.b = pp.a * lb + pp.b * ld;
88 p.c = pp.c * la + pp.d * lc;
89 p.d = pp.c * lb + pp.d * ld;
90 p.worldRot = pp.worldRot + p.rotation;
91 p.worldSX = pp.worldSX * p.scaleX;
92 p.worldSY = pp.worldSY * p.scaleY;
93 }
94 }
95}
96
98 checkBone(index);
99 return bones_[static_cast<size_t>(index)].x;
100}
102 checkBone(index);
103 return bones_[static_cast<size_t>(index)].y;
104}
106 checkBone(index);
107 return bones_[static_cast<size_t>(index)].rotation;
108}
110 checkBone(index);
111 return bones_[static_cast<size_t>(index)].scaleX;
112}
114 checkBone(index);
115 return bones_[static_cast<size_t>(index)].scaleY;
116}
117
119 checkBone(index);
120 bones_[static_cast<size_t>(index)].x = x;
121}
123 checkBone(index);
124 bones_[static_cast<size_t>(index)].y = y;
125}
127 checkBone(index);
128 bones_[static_cast<size_t>(index)].rotation = degrees;
129}
131 checkBone(index);
132 bones_[static_cast<size_t>(index)].scaleX = sx;
133}
135 checkBone(index);
136 bones_[static_cast<size_t>(index)].scaleY = sy;
137}
138
140 checkBone(index);
141 return bones_[static_cast<size_t>(index)].worldX;
142}
144 checkBone(index);
145 return bones_[static_cast<size_t>(index)].worldY;
146}
148 checkBone(index);
149 return bones_[static_cast<size_t>(index)].worldRot;
150}
152 checkBone(index);
153 return bones_[static_cast<size_t>(index)].worldSX;
154}
156 checkBone(index);
157 return bones_[static_cast<size_t>(index)].worldSY;
158}
159
160void SpineSkeleton::getBoneWorldMatrix(int index, float &a, float &b, float &c, float &d) const {
161 checkBone(index);
162 const BonePose &p = bones_[static_cast<size_t>(index)];
163 a = p.a;
164 b = p.b;
165 c = p.c;
166 d = p.d;
167}
168
169std::string SpineSkeleton::getSlotAttachmentName(int slotIndex) const {
170 checkSlot(slotIndex);
171 return slotAttachments_[static_cast<size_t>(slotIndex)];
172}
173
174void SpineSkeleton::setSlotAttachmentName(int slotIndex, const std::string &name) {
175 checkSlot(slotIndex);
176 slotAttachments_[static_cast<size_t>(slotIndex)] = name;
177}
178
180 checkSlot(slotIndex);
181 const std::string &name = slotAttachments_[static_cast<size_t>(slotIndex)];
182 if (name.empty()) return nullptr;
183 const auto *att = data_->findAttachment(skinIndex_, slotIndex, name);
184 if (att) return att;
185 // Fallback to default skin
186 int def = data_->getDefaultSkin();
187 if (def >= 0 && def != skinIndex_) return data_->findAttachment(def, slotIndex, name);
188 return nullptr;
189}
190
191} // namespace eve::animation
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float degrees
Definition CardTypes.cpp:35
glm::vec4 p[6]
std::int32_t c
std::array< float, 4 > rotation
std::int32_t parent
std::string name
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
#define M_PI
int idx
float d
uint32_t index
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
Spine skeleton JSON data (bones / slots / skins / animations).
int findSkin(const std::string &name) const
Finds skin.
const RegionAttachment * findAttachment(int skinIndex, int slotIndex, const std::string &name) const
const SlotData & slot(int i) const
int getBoneCount() const
Returns the bone count.
int getDefaultSkin() const
Returns the default skin.
int getSlotCount() const
Returns the slot count.
const BoneData & bone(int i) const
void setBoneLocalScaleY(int index, float sy)
Sets the bone local scale y.
float getBoneWorldScaleY(int index) const
Returns the bone world scale y.
float getBoneLocalScaleY(int index) const
Returns the bone local scale y.
float getBoneWorldScaleX(int index) const
Returns the bone world scale x.
float getBoneWorldRotation(int index) const
Returns the bone world rotation.
void setBoneLocalScaleX(int index, float sx)
Sets the bone local scale x.
float getBoneLocalScaleX(int index) const
Returns the bone local scale x.
bool setSkin(const std::string &name)
Sets the skin.
void setToSetupPose()
Sets the to setup pose.
SpineSkeleton(SpineSkeletonData *data)
Spine skeleton.
float getBoneLocalX(int index) const
Returns the bone local x.
const SpineSkeletonData::RegionAttachment * getSlotRegion(int slotIndex) const
Returns the slot region.
std::string getSlotAttachmentName(int slotIndex) const
Returns the slot attachment name.
int getSlotCount() const
Returns the slot count.
void getBoneWorldMatrix(int index, float &a, float &b, float &c, float &d) const
World 2x2 matrix columns (a,c) / (b,d) used for local→world offset.
float getBoneLocalRotation(int index) const
Returns the bone local rotation.
void setBoneLocalRotation(int index, float degrees)
Sets the bone local rotation.
int getBoneCount() const
Returns the bone count.
float getBoneWorldY(int index) const
Returns the bone world y.
void setBoneLocalX(int index, float x)
Sets the bone local x.
void updateWorldTransform()
Updates world transform.
void setSlotAttachmentName(int slotIndex, const std::string &name)
Sets the slot attachment name.
float getBoneLocalY(int index) const
Returns the bone local y.
void setBoneLocalY(int index, float y)
Sets the bone local y.
float getBoneWorldX(int index) const
Returns the bone world x.