5#include "../../../MacroDef.h"
6#include "DAEAnimationLoader.h"
10#include "../../MoreString.h"
11#include "../../../Manager/ResMgr.h"
12#include "../../../Manager/EngineCore.h"
16const mat4 CORRECTION = mat4::Identity();
19DAEAnimationLoader::DAEAnimationLoader() =
default;
21DAEAnimationLoader::~DAEAnimationLoader() {
23 if(m_animationData ==
nullptr)
return;
24 for (
auto frame : m_animationData->keyFrames) {
25 for (
auto joint : frame->jointTransforms) {
28 frame->jointTransforms.clear();
31 m_animationData->keyFrames.clear();
32 SAFE_DELETE(m_animationData);
35bool DAEAnimationLoader::Load(
const char* path, std::string name) {
36 m_name = std::move(name);
38 m_root =
XFILE(path).getRoot();
39 XNode collada = m_root->getChild(
"COLLADA");
42 if(!collada.hasChild(
"library_animations"))
return false;
43 if(!collada.hasChild(
"library_visual_scenes"))
return false;
45 m_animation = collada.getChild(
"library_animations");
46 m_joint = collada.getChild(
"library_visual_scenes");
48 if(!m_animation.getChild(
"animation").hasChild(
"source"))
return false;
49 if(!m_joint.getChild(
"visual_scene").hasChild(
"node"))
return false;
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);
69std::string DAEAnimationLoader::findRootJointName() {
70 XNode skeleton = m_joint.getChild(
"visual_scene").getNodeByAttribute(
"node",
"id",
"Armature");
71 return skeleton.getChild(
"node").getAttribute(
"id").value;
74std::vector<float> DAEAnimationLoader::getKeyTimes() {
75 XNode timeData = m_animation.getChild(
"animation").getChild(
"source").getChild(
"float_array");
76 return timeData.value.toFloatVector();
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) {
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);
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];
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);
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]);
118 mat4 transform =
mat4(&matrixData[0]);
119 transform = transform.Transposed();
123 transform *= CORRECTION;
126 keyFrames[i]->jointTransforms.push_back(