CSEngine
Loading...
Searching...
No Matches
DAEAnimationLoader.cpp
1//
2// Created by ounols on 19. 3. 31.
3//
4
5#include "../../../MacroDef.h"
6#include "DAEAnimationLoader.h"
7
8#include <utility>
9
10#include "../../MoreString.h"
11#include "../../../Manager/ResMgr.h"
12#include "../../../Manager/EngineCore.h"
13
14using namespace CSE;
15
16const mat4 CORRECTION = /*mat4::RotateX(90)*/ mat4::Identity();
17
18
19DAEAnimationLoader::DAEAnimationLoader() = default;
20
21DAEAnimationLoader::~DAEAnimationLoader() {
22 SAFE_DELETE(m_root);
23 if(m_animationData == nullptr) return;
24 for (auto frame : m_animationData->keyFrames) {
25 for (auto joint : frame->jointTransforms) {
26 SAFE_DELETE(joint);
27 }
28 frame->jointTransforms.clear();
29 SAFE_DELETE(frame);
30 }
31 m_animationData->keyFrames.clear();
32 SAFE_DELETE(m_animationData);
33}
34
35bool DAEAnimationLoader::Load(const char* path, std::string name) {
36 m_name = std::move(name);
37
38 m_root = XFILE(path).getRoot();
39 XNode collada = m_root->getChild("COLLADA");
40
41#ifdef __EMSCRIPTEN__
42 if(!collada.hasChild("library_animations")) return false;
43 if(!collada.hasChild("library_visual_scenes")) return false;
44#endif
45 m_animation = collada.getChild("library_animations");
46 m_joint = collada.getChild("library_visual_scenes");
47#ifdef __EMSCRIPTEN__
48 if(!m_animation.getChild("animation").hasChild("source")) return false;
49 if(!m_joint.getChild("visual_scene").hasChild("node")) return false;
50#endif
51 LoadAnimation();
52 return true;
53}
54
55void DAEAnimationLoader::LoadAnimation() {
56 std::string rootNode = findRootJointName();
57 std::vector<float> times = getKeyTimes();
58 float duration = times[times.size() - 1];
59 std::vector<KeyFrameData*> keyFrames = initKeyFrames(times);
60 std::vector<XNode> animationNodes = m_animation.children;
61 for (const XNode& jointNode : animationNodes) {
62 if (jointNode.name != "animation") continue;
63 loadJointTransforms(keyFrames, jointNode, rootNode);
64 }
65
66 m_animationData = new AnimationData(duration, keyFrames);
67}
68
69std::string DAEAnimationLoader::findRootJointName() {
70 XNode skeleton = m_joint.getChild("visual_scene").getNodeByAttribute("node", "id", "Armature");
71 return skeleton.getChild("node").getAttribute("id").value;
72}
73
74std::vector<float> DAEAnimationLoader::getKeyTimes() {
75 XNode timeData = m_animation.getChild("animation").getChild("source").getChild("float_array");
76 return timeData.value.toFloatVector();
77}
78
79std::vector<KeyFrameData*> DAEAnimationLoader::initKeyFrames(const std::vector<float>& times) {
80 std::vector<KeyFrameData*> frames;
81 frames.reserve(times.size());
82 for (float time : times) {
83 frames.push_back(new KeyFrameData(time));
84 }
85 return frames;
86}
87
88void
89DAEAnimationLoader::loadJointTransforms(std::vector<KeyFrameData*> frames, const XNode& jointData, const std::string& rootNodeId) {
90 std::string jointNameId = getJointName(jointData);
91 std::string dataId = getDataId(jointData);
92 const XNode& transformData = jointData.getNodeByAttribute("source", "id", dataId.c_str());
93 std::vector<float> rawData = transformData.getChild("float_array").value.toFloatVector();
94 processTransforms(jointNameId, rawData, std::move(frames), jointNameId == rootNodeId);
95
96}
97
98std::string DAEAnimationLoader::getJointName(const XNode& jointData) {
99 const XNode& channelNode = jointData.getChild("channel");
100 std::string data = channelNode.getAttribute("target").value;
101 return split(data, '/')[0];
102}
103
104std::string DAEAnimationLoader::getDataId(const XNode& jointData) {
105 XNode node = jointData.getChild("sampler").getNodeByAttribute("input", "semantic", "OUTPUT");
106 return node.getAttribute("source").value.substr(1);
107}
108
109void DAEAnimationLoader::processTransforms(const std::string& jointName,
110 std::vector<float> rawData, std::vector<KeyFrameData*> keyFrames, bool root) {
111 for (int i = 0; i < keyFrames.size(); i++) {
112 std::vector<float> matrixData;
113 matrixData.reserve(16);
114 for (int j = 0; j < 16; j++) {
115 matrixData.push_back(rawData[i * 16 + j]);
116 }
117
118 mat4 transform = mat4(&matrixData[0]);
119 transform = transform.Transposed();
120
121 if (root) {
122 //because up axis in Blender is different to up axis in game
123 transform *= CORRECTION;
124 }
125
126 keyFrames[i]->jointTransforms.push_back(
127 new JointTransformData(CORE->GetCore(ResMgr)->GetStringHash(jointName), jointName, transform));
128 }
129}
Definition XML.h:77
Definition XML.h:43