载入中...
搜索中...
未找到
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
97float SpineSkeleton::getBoneLocalX(int index) const {
98 checkBone(index);
99 return bones_[static_cast<size_t>(index)].x;
100}
101float SpineSkeleton::getBoneLocalY(int index) const {
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}
109float SpineSkeleton::getBoneLocalScaleX(int index) const {
110 checkBone(index);
111 return bones_[static_cast<size_t>(index)].scaleX;
112}
113float SpineSkeleton::getBoneLocalScaleY(int index) const {
114 checkBone(index);
115 return bones_[static_cast<size_t>(index)].scaleY;
116}
117
118void SpineSkeleton::setBoneLocalX(int index, float x) {
119 checkBone(index);
120 bones_[static_cast<size_t>(index)].x = x;
121}
122void SpineSkeleton::setBoneLocalY(int index, float y) {
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}
130void SpineSkeleton::setBoneLocalScaleX(int index, float sx) {
131 checkBone(index);
132 bones_[static_cast<size_t>(index)].scaleX = sx;
133}
134void SpineSkeleton::setBoneLocalScaleY(int index, float sy) {
135 checkBone(index);
136 bones_[static_cast<size_t>(index)].scaleY = sy;
137}
138
139float SpineSkeleton::getBoneWorldX(int index) const {
140 checkBone(index);
141 return bones_[static_cast<size_t>(index)].worldX;
142}
143float SpineSkeleton::getBoneWorldY(int index) const {
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}
151float SpineSkeleton::getBoneWorldScaleX(int index) const {
152 checkBone(index);
153 return bones_[static_cast<size_t>(index)].worldSX;
154}
155float SpineSkeleton::getBoneWorldScaleY(int index) const {
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 degrees
Definition CardTypes.cpp:33
int y
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
uint32_t a
uint32_t b
uint32_t c
int idx
glm::vec4 p[6]
Light2D::Data * data
const char * name
Definition RockMesh.cpp:21
#define M_PI
Definition SpineAnim.cpp:16
int d
int parent
Definition TreeMesh.cpp:175
Spine skeleton JSON data (bones / slots / skins / animations).
int findSkin(const std::string &name) const
const RegionAttachment * findAttachment(int skinIndex, int slotIndex, const std::string &name) const
const SlotData & slot(int i) const
const BoneData & bone(int i) const
void setBoneLocalScaleY(int index, float sy)
float getBoneWorldScaleY(int index) const
float getBoneLocalScaleY(int index) const
float getBoneWorldScaleX(int index) const
float getBoneWorldRotation(int index) const
void setBoneLocalScaleX(int index, float sx)
float getBoneLocalScaleX(int index) const
bool setSkin(const std::string &name)
SpineSkeleton(SpineSkeletonData *data)
float getBoneLocalX(int index) const
const SpineSkeletonData::RegionAttachment * getSlotRegion(int slotIndex) const
std::string getSlotAttachmentName(int slotIndex) const
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
void setBoneLocalRotation(int index, float degrees)
float getBoneWorldY(int index) const
void setBoneLocalX(int index, float x)
void setSlotAttachmentName(int slotIndex, const std::string &name)
float getBoneLocalY(int index) const
void setBoneLocalY(int index, float y)
float getBoneWorldX(int index) const