-
Notifications
You must be signed in to change notification settings - Fork 24
/
AvatarPoseSequence.cpp
74 lines (65 loc) · 2.4 KB
/
AvatarPoseSequence.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "Avatar.h"
#include <fstream>
#include <boost/filesystem.hpp>
#include "Version.h"
#include "Util.h"
namespace ark {
Eigen::VectorXd AvatarPoseSequence::getFrame(size_t frame_id) const {
if (preloaded) return data.col(frame_id);
std::ifstream ifs(sequencePath, std::ios::in | std::ios::binary);
ifs.seekg(frame_id * frameSize * sizeof(double), std::ios_base::beg);
Eigen::VectorXd result(frameSize);
ifs.read(reinterpret_cast<char*>(result.data()),
frameSize * sizeof(double));
return result;
}
AvatarPoseSequence::AvatarPoseSequence(const std::string& pose_sequence_path) {
using namespace boost::filesystem;
path seqPath =
pose_sequence_path.empty()
? util::resolveRootPath("data/avatar-mocap/cmu-mocap.dat")
: pose_sequence_path;
path metaPath(std::string(seqPath.string()).append(".txt"));
if (!exists(seqPath) || !exists(metaPath)) {
numFrames = 0;
return;
}
sequencePath = seqPath.string();
std::ifstream metaIfs(metaPath.string());
size_t nSubseq, frameSizeBytes, subseqStart;
metaIfs >> nSubseq >> numFrames >> frameSizeBytes;
std::string subseqName;
for (int sid = 0; sid < nSubseq; ++sid) {
metaIfs >> subseqStart >> subseqName;
subsequences[subseqName] = subseqStart / frameSizeBytes;
}
metaIfs.close();
frameSize = frameSizeBytes / sizeof(double);
}
void AvatarPoseSequence::poseAvatar(Avatar& ava, size_t frame_id) const {
if (preloaded) {
auto frameData = data.col(frame_id);
ava.p.noalias() = frameData.head<3>();
Eigen::Quaterniond q;
for (int i = 0; i < ava.r.size(); ++i) {
q.coeffs().noalias() = frameData.segment<4>(i * 4 + 3);
ava.r[i].noalias() = q.toRotationMatrix();
}
} else {
Eigen::VectorXd frameData = getFrame(frame_id);
ava.p = frameData.head<3>();
Eigen::Quaterniond q;
for (int i = 0; i < ava.r.size(); ++i) {
q.coeffs().noalias() = frameData.segment<4>(i * 4 + 3);
ava.r[i].noalias() = q.toRotationMatrix();
}
}
}
void AvatarPoseSequence::preload() {
data.resize(frameSize, numFrames);
std::ifstream ifs(sequencePath, std::ios::in | std::ios::binary);
ifs.read(reinterpret_cast<char*>(data.data()),
numFrames * frameSize * sizeof(double));
preloaded = true;
}
} // namespace ark