载入中...
搜索中...
未找到
AnimImporter.cpp
浏览该文件的文档.
4
5#include "common/Exception.h"
6
7#include <fstream>
8#include <sstream>
9
10namespace eve::animation {
11
12namespace {
13
14std::string trim(const std::string &s) {
15 size_t a = 0;
16 while (a < s.size() && (s[a] == ' ' || s[a] == '\t' || s[a] == '\r')) ++a;
17 size_t b = s.size();
18 while (b > a && (s[b - 1] == ' ' || s[b - 1] == '\t' || s[b - 1] == '\r')) --b;
19 return s.substr(a, b - a);
20}
21
22} // namespace
23
25 if (!skeleton || !clip) throw Exception("AnimImporter.exportAnimationFixtureText: null argument");
26 std::ostringstream out;
27 out << "EVA 1\n";
28 out << "skeleton " << skeleton->getBoneCount() << "\n";
29 for (int i = 0; i < skeleton->getBoneCount(); ++i) {
30 out << "bone " << i << " " << skeleton->getParent(i) << " " << skeleton->getBoneName(i)
31 << "\n";
32 out << "bind " << i << " " << skeleton->getBindPositionX(i) << " "
33 << skeleton->getBindPositionY(i) << " " << skeleton->getBindPositionZ(i) << " "
34 << skeleton->getBindRotationX(i) << " " << skeleton->getBindRotationY(i) << " "
35 << skeleton->getBindRotationZ(i) << " " << skeleton->getBindRotationW(i) << " "
36 << skeleton->getBindScaleX(i) << " " << skeleton->getBindScaleY(i) << " "
37 << skeleton->getBindScaleZ(i) << "\n";
38 }
39 out << "clip " << clip->getName() << "\n";
40 out << "duration " << clip->getDuration() << "\n";
41 out << "loop " << (clip->getLoop() ? 1 : 0) << "\n";
42 out << "rate " << clip->getSampleRate() << "\n";
43 for (int i = 0; i < clip->getSyncMarkerCount(); ++i)
44 out << "sync " << clip->getSyncMarkerTime(i) << " " << clip->getSyncMarkerName(i) << "\n";
45 for (int b = 0; b < skeleton->getBoneCount(); ++b) {
46 const int np = clip->getPositionKeyCount(b);
47 const int nr = clip->getRotationKeyCount(b);
48 const int ns = clip->getScaleKeyCount(b);
49 if (np + nr + ns == 0) continue;
50 out << "track " << b << " " << np << " " << nr << " " << ns << "\n";
51 for (int i = 0; i < np; ++i) {
52 out << "p " << clip->getPositionKeyTime(b, i) << " " << clip->getPositionKeyX(b, i)
53 << " " << clip->getPositionKeyY(b, i) << " " << clip->getPositionKeyZ(b, i) << "\n";
54 }
55 for (int i = 0; i < nr; ++i) {
56 out << "r " << clip->getRotationKeyTime(b, i) << " " << clip->getRotationKeyX(b, i)
57 << " " << clip->getRotationKeyY(b, i) << " " << clip->getRotationKeyZ(b, i) << " "
58 << clip->getRotationKeyW(b, i) << "\n";
59 }
60 for (int i = 0; i < ns; ++i) {
61 out << "s " << clip->getScaleKeyTime(b, i) << " " << clip->getScaleKeyX(b, i) << " "
62 << clip->getScaleKeyY(b, i) << " " << clip->getScaleKeyZ(b, i) << "\n";
63 }
64 }
65 out << "end\n";
66 return out.str();
67}
68
69void AnimImporter::importAnimationFixtureText(const std::string &text, AnimSkeleton **skeletonOut,
70 AnimClip **clipOut) {
71 if (!skeletonOut || !clipOut) throw Exception("AnimImporter.importAnimationFixtureText: null out");
72 *skeletonOut = nullptr;
73 *clipOut = nullptr;
74
75 auto *skeleton = new AnimSkeleton();
76 AnimClip *clip = nullptr;
77 int curBone = -1;
78
79 std::istringstream in(text);
80 std::string line;
81 try {
82 while (std::getline(in, line)) {
83 line = trim(line);
84 if (line.empty() || line[0] == '#') continue;
85 std::istringstream ls(line);
86 std::string tag;
87 ls >> tag;
88 if (tag == "EVA") {
89 int ver = 0;
90 ls >> ver;
91 if (ver != 1) throw Exception("AnimImporter.importAnimationFixtureText: unsupported version");
92 } else if (tag == "skeleton") {
93 // informational
94 } else if (tag == "bone") {
95 int idx = -1, parent = -1;
96 std::string name;
97 ls >> idx >> parent;
98 std::getline(ls, name);
99 name = trim(name);
100 if (name.empty()) throw Exception("AnimImporter.importAnimationFixtureText: empty bone name");
101 const int id = skeleton->addBone(name, parent);
102 if (id != idx) {
103 throw Exception("AnimImporter.importAnimationFixtureText: bone index mismatch");
104 }
105 } else if (tag == "bind") {
106 int idx = -1;
107 float px, py, pz, qx, qy, qz, qw, sx, sy, sz;
108 ls >> idx >> px >> py >> pz >> qx >> qy >> qz >> qw >> sx >> sy >> sz;
109 skeleton->setBindPosition(idx, px, py, pz);
110 skeleton->setBindRotation(idx, qx, qy, qz, qw);
111 skeleton->setBindScale(idx, sx, sy, sz);
112 } else if (tag == "clip") {
113 std::string name;
114 std::getline(ls, name);
115 name = trim(name);
116 clip = new AnimClip(name.empty() ? "clip" : name);
117 } else if (tag == "duration") {
118 if (!clip) throw Exception("AnimImporter.importAnimationFixtureText: duration before clip");
119 float d = 0.f;
120 ls >> d;
121 clip->setDuration(d);
122 } else if (tag == "loop") {
123 if (!clip) throw Exception("AnimImporter.importAnimationFixtureText: loop before clip");
124 int v = 1;
125 ls >> v;
126 clip->setLoop(v != 0);
127 } else if (tag == "rate") {
128 if (!clip) throw Exception("AnimImporter.importAnimationFixtureText: rate before clip");
129 float r = 30.f;
130 ls >> r;
131 clip->setSampleRate(r);
132 } else if (tag == "sync") {
133 if (!clip) throw Exception("AnimImporter.importAnimationFixtureText: sync marker before clip");
134 float t = 0.f;
135 std::string name;
136 ls >> t;
137 std::getline(ls, name);
138 name = trim(name);
139 clip->addSyncMarker(t, name);
140 } else if (tag == "track") {
141 if (!clip) throw Exception("AnimImporter.importAnimationFixtureText: track before clip");
142 int np = 0, nr = 0, ns = 0;
143 ls >> curBone >> np >> nr >> ns;
144 (void)np;
145 (void)nr;
146 (void)ns;
147 } else if (tag == "p") {
148 float t, x, y, z;
149 ls >> t >> x >> y >> z;
150 clip->addPositionKey(curBone, t, x, y, z);
151 } else if (tag == "r") {
152 float t, x, y, z, w;
153 ls >> t >> x >> y >> z >> w;
154 clip->addRotationKey(curBone, t, x, y, z, w);
155 } else if (tag == "s") {
156 float t, x, y, z;
157 ls >> t >> x >> y >> z;
158 clip->addScaleKey(curBone, t, x, y, z);
159 } else if (tag == "end") {
160 break;
161 }
162 }
163 if (!clip) throw Exception("AnimImporter.importAnimationFixtureText: missing clip");
164 *skeletonOut = skeleton;
165 *clipOut = clip;
166 } catch (...) {
167 delete skeleton;
168 delete clip;
169 throw;
170 }
171}
172
174 AnimClip **clipOut) {
175 std::ifstream in(path);
176 if (!in) throw Exception("AnimImporter.importAnimationFixtureTextFile: cannot open %s", path.c_str());
177 std::ostringstream ss;
178 ss << in.rdbuf();
179 importAnimationFixtureText(ss.str(), skeletonOut, clipOut);
180}
181
182} // namespace eve::animation
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
const std::string & s
float py
float pz
glm::vec4 clip
double r
float v
std::vector< Colorf > px
std::string text
std::int32_t parent
std::string name
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
const std::string * tag
int idx
std::string path
Definition PlayHost.cpp:110
float d
float t
float qy
float qx
float qw
float qz
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
Keyframed skeletal animation clip (local TRS tracks per bone). Script type: AnimClip.
Definition AnimClip.h:145
static std::string exportAnimationFixtureText(const AnimSkeleton *skeleton, const AnimClip *clip)
Serialize skeleton + clip to a compact text format (no mesh). Used to ship Mixamo-derived test fixtur...
static void importAnimationFixtureTextFile(const std::string &path, AnimSkeleton **skeletonOut, AnimClip **clipOut)
Load from an *.anim.txt fixture path.
static void importAnimationFixtureText(const std::string &text, AnimSkeleton **skeletonOut, AnimClip **clipOut)
Load skeleton+clip from fixture text (new'd; caller owns).
3D bone hierarchy + bind-pose local TRS for skeletal animation. Independent of ik::Skeleton3D (FABRIK...
float getBindPositionY(int boneIndex) const
Returns the bind position y.
float getBindScaleX(int boneIndex) const
Returns the bind scale x.
int getBoneCount() const
Returns the bone count.
int getParent(int boneIndex) const
Returns the parent.
float getBindPositionZ(int boneIndex) const
Returns the bind position z.
float getBindRotationW(int boneIndex) const
Returns the bind rotation w.
float getBindScaleY(int boneIndex) const
Returns the bind scale y.
float getBindRotationY(int boneIndex) const
Returns the bind rotation y.
float getBindScaleZ(int boneIndex) const
Returns the bind scale z.
float getBindPositionX(int boneIndex) const
Returns the bind position x.
float getBindRotationZ(int boneIndex) const
Returns the bind rotation z.
float getBindRotationX(int boneIndex) const
Returns the bind rotation x.
std::string getBoneName(int boneIndex) const
Returns the bone name.