Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
Skeleton.cpp
Go to the documentation of this file.
2 
4 
5 #ifdef USING_OPENGL
7 #endif
8 #ifdef USING_VULKAN
10 #endif
11 
12 #include <iostream>
13 #include <ThirdParty/glm/glm/gtc/matrix_transform.hpp>
14 
15 namespace Engine {
16 
17  Skeleton::Skeleton(const aiScene* scene)
18  {
19  this->scene = scene;
20 
21  if (scene->HasAnimations()) {
22 
23  animated = true;
24 
25  speed = 1.f;
26 
27  boneData.resize(0xff, { glm::mat4() });
28 
29  rootBone = new Bone_t;
30 
31  rootBone->boneDataIndex = -1;
32  rootBone->parent = nullptr;
33 
34  ReadBones(rootBone, scene->mRootNode);
35 
36  for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
37  Animation_t* animation = new Animation_t;
38  animation->name = eastl::string(scene->mAnimations[i]->mName.C_Str());
39  animation->duration = static_cast<float>(scene->mAnimations[i]->mDuration);
40  animation->ticksPerSecond = static_cast<float>(scene->mAnimations[i]->mTicksPerSecond);
41 
42  animations.push_back(animation);
43 
44  animationMap[animation->name] = animations.size() - 1;
45 
46  currentAnimationIndex = animations.size() - 1;
47 
48  for (unsigned int j = 0; j < scene->mAnimations[i]->mNumChannels; ++j) {
49  AnimationNode_t animationNode = {};
50  aiNodeAnim* node = scene->mAnimations[i]->mChannels[j];
51 
52  eastl::map<eastl::string, Bone_t*>::iterator it = boneMap.find(eastl::string(node->mNodeName.C_Str()));
53 
54  if (it != boneMap.end()) {
55  animationNode.bone = it->second;
56  }
57  else {
58  std::cout << "[ERROR] Animation using bones not contained in skeleton" << std::endl;
59  continue;
60  }
61 
62  animationNode.positionKeys.resize(node->mNumPositionKeys);
63  animationNode.rotationKeys.resize(node->mNumRotationKeys);
64  animationNode.scalingKeys.resize(node->mNumScalingKeys);
65 
66  for (unsigned int k = 0; k < node->mNumPositionKeys; ++k) {
67  AnimationPositionKey_t key = {};
68  key.time = static_cast<float>(node->mPositionKeys[k].mTime);
69  key.position = glm::vec3(node->mPositionKeys[k].mValue.x,
70  node->mPositionKeys[k].mValue.y,
71  node->mPositionKeys[k].mValue.z);
72 
73  animationNode.positionKeys[k] = key;
74  }
75 
76  for (unsigned int k = 0; k < node->mNumRotationKeys; ++k) {
77  AnimationRotationKey_t key = {};
78  key.time = static_cast<float>(node->mRotationKeys[k].mTime);
79  key.rotation = glm::quat();
80  key.rotation.x = node->mRotationKeys[k].mValue.x;
81  key.rotation.y = node->mRotationKeys[k].mValue.y;
82  key.rotation.z = node->mRotationKeys[k].mValue.z;
83  key.rotation.w = node->mRotationKeys[k].mValue.w;
84 
85  animationNode.rotationKeys[k] = key;
86  }
87 
88  for (unsigned int k = 0; k < node->mNumScalingKeys; ++k) {
89  AnimationScalingKey_t key = {};
90  key.time = static_cast<float>(node->mScalingKeys[k].mTime);
91  key.scale = glm::vec3(node->mScalingKeys[k].mValue.x,
92  node->mScalingKeys[k].mValue.y,
93  node->mScalingKeys[k].mValue.z);
94 
95  animationNode.scalingKeys[k] = key;
96  }
97 
98  animationNode.preAnimBehaviour = node->mPreState;
99  animationNode.postAnimBehaviour = node->mPostState;
100 
101  animation->nodes.push_back(animationNode);
102 
103  }
104 
105  eastl::vector<float> animationBuffer;
106 
107  currentAnimation = animation;
108 
109  paused = false;
110 
111  animationBuffer.resize(static_cast<size_t>(animation->duration) * 3 * 256 * 4);
112 
113  size_t currentRow = 0;
114 
115  for (float t = 0.f, inc = 1.f / animation->ticksPerSecond,
116  duration = animation->duration/animation->ticksPerSecond;
117  t < duration;
118  t+=inc) {
119  time = t;
120  Update(0.f);
121 
122  for (size_t j = 0, size = boneData.size(); j < size; ++j) {
123  glm::mat4 transform = boneData[j].transform;
124 
125  glm::vec4 translate = transform[3];
126  transform[3] = glm::vec4(0.f, 0.f, 0.f, 1.f);
127 
128  glm::vec3 scale = glm::vec3(
129  glm::length(glm::vec3(transform[0][0], transform[0][1], transform[0][2])),
130  glm::length(glm::vec3(transform[1][0], transform[1][1], transform[1][2])),
131  glm::length(glm::vec3(transform[2][0], transform[2][1], transform[2][2]))
132  );
133 
134  transform[0][0] /= scale.x;
135  transform[0][1] /= scale.x;
136  transform[0][2] /= scale.x;
137  transform[1][0] /= scale.y;
138  transform[1][1] /= scale.y;
139  transform[1][2] /= scale.y;
140  transform[2][0] /= scale.z;
141  transform[2][1] /= scale.z;
142  transform[2][2] /= scale.z;
143 
144  glm::quat rotation = glm::quat_cast(transform);
145 
146  animationBuffer[(currentRow * 256 * 4) + j * 4] = translate.x;
147  animationBuffer[(currentRow * 256 * 4) + j * 4 + 1] = translate.y;
148  animationBuffer[(currentRow * 256 * 4) + j * 4 + 2] = translate.z;
149  animationBuffer[(currentRow * 256 * 4) + j * 4 + 3] = translate.w;
150 
151  animationBuffer[((currentRow + 1) * 256 * 4) + j * 4] = scale.x;
152  animationBuffer[((currentRow + 1) * 256 * 4) + j * 4 + 1] = scale.y;
153  animationBuffer[((currentRow + 1) * 256 * 4) + j * 4 + 2] = scale.z;
154 
155  animationBuffer[((currentRow + 2) * 256 * 4) + j * 4] = rotation.x;
156  animationBuffer[((currentRow + 2) * 256 * 4) + j * 4 + 1] = rotation.y;
157  animationBuffer[((currentRow + 2) * 256 * 4) + j * 4 + 2] = rotation.z;
158  animationBuffer[((currentRow + 2) * 256 * 4) + j * 4 + 3] = rotation.w;
159  }
160 
161  currentRow += 3;
162 
163  }
164 
165 #ifdef USING_VULKAN
166  animation->texture = eastl::shared_ptr<VulkanTexture>(new VulkanTexture(256, static_cast<int>(animation->duration * 3.f)));
167  animation->texture->CreateTextureWithData(reinterpret_cast<stbi_uc*>(animationBuffer.data()), false, TextureDataSize::S_INT, true);
168 
169  VkSamplerCreateInfo samplerInfo = {};
170  samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
171  samplerInfo.magFilter = VK_FILTER_NEAREST;
172  samplerInfo.minFilter = VK_FILTER_NEAREST;
173  samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
174  samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
175  samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
176  samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
177  samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
178  samplerInfo.anisotropyEnable = VK_FALSE;
179  samplerInfo.compareEnable = VK_FALSE;
180  samplerInfo.unnormalizedCoordinates = VK_TRUE;
181 
182  eastl::static_pointer_cast<VulkanTexture, Texture>(animation->texture)->SetSampler(samplerInfo);
183 #endif
184 #ifdef USING_OPENGL
185  animation->texture = eastl::shared_ptr<OpenGLTexture>(new OpenGLTexture(256, static_cast<int>(animation->duration * 3.f)));
186  animation->texture->CreateTextureWithData(reinterpret_cast<stbi_uc*>(animationBuffer.data()), false, TextureDataSize::S_INT, true);
187 #endif
188  }
189 
190  }
191  else {
192  animated = false;
193  }
194  }
195 
196  void Skeleton::LoadAnimationSet(const aiScene * scene, eastl::vector<eastl::string> names)
197  {
198  if (scene->HasAnimations()) {
199 
200  for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
201  Animation_t* animation = new Animation_t;
202  if (names.size() > i) {
203  animation->name = names[i];
204  if(animation->name=="")
205  animation->name = eastl::string(scene->mAnimations[i]->mName.C_Str());
206  }
207  else {
208  animation->name = eastl::string(scene->mAnimations[i]->mName.C_Str());
209  }
210  animation->duration = static_cast<float>(scene->mAnimations[i]->mDuration);
211  animation->ticksPerSecond = static_cast<float>(scene->mAnimations[i]->mTicksPerSecond);
212 
213  animations.push_back(animation);
214 
215  animationMap[animation->name] = animations.size() - 1;
216 
217  currentAnimationIndex = animations.size() - 1;
218 
219  for (unsigned int j = 0; j < scene->mAnimations[i]->mNumChannels; ++j) {
220  AnimationNode_t animationNode = {};
221  aiNodeAnim* node = scene->mAnimations[i]->mChannels[j];
222 
223  eastl::map<eastl::string, Bone_t*>::iterator it = boneMap.find(eastl::string(node->mNodeName.C_Str()));
224 
225  if (it != boneMap.end()) {
226  animationNode.bone = it->second;
227  }
228  else {
229  std::cout << "[ERROR] Animation using bones not contained in skeleton" << std::endl;
230  continue;
231  }
232 
233  animationNode.positionKeys.resize(node->mNumPositionKeys);
234  animationNode.rotationKeys.resize(node->mNumRotationKeys);
235  animationNode.scalingKeys.resize(node->mNumScalingKeys);
236 
237  for (unsigned int k = 0; k < node->mNumPositionKeys; ++k) {
238  AnimationPositionKey_t key = {};
239  key.time = static_cast<float>(node->mPositionKeys[k].mTime);
240  key.position = glm::vec3(node->mPositionKeys[k].mValue.x,
241  node->mPositionKeys[k].mValue.y,
242  node->mPositionKeys[k].mValue.z);
243 
244  animationNode.positionKeys[k] = key;
245  }
246 
247  for (unsigned int k = 0; k < node->mNumRotationKeys; ++k) {
248  AnimationRotationKey_t key = {};
249  key.time = static_cast<float>(node->mRotationKeys[k].mTime);
250  key.rotation = glm::quat();
251  key.rotation.x = node->mRotationKeys[k].mValue.x;
252  key.rotation.y = node->mRotationKeys[k].mValue.y;
253  key.rotation.z = node->mRotationKeys[k].mValue.z;
254  key.rotation.w = node->mRotationKeys[k].mValue.w;
255 
256  animationNode.rotationKeys[k] = key;
257  }
258 
259  for (unsigned int k = 0; k < node->mNumScalingKeys; ++k) {
260  AnimationScalingKey_t key = {};
261  key.time = static_cast<float>(node->mScalingKeys[k].mTime);
262  key.scale = glm::vec3(node->mScalingKeys[k].mValue.x,
263  node->mScalingKeys[k].mValue.y,
264  node->mScalingKeys[k].mValue.z);
265 
266  animationNode.scalingKeys[k] = key;
267  }
268 
269  animationNode.preAnimBehaviour = node->mPreState;
270  animationNode.postAnimBehaviour = node->mPostState;
271 
272  animation->nodes.push_back(animationNode);
273 
274  }
275 
276  eastl::vector<float> animationBuffer;
277 
278  currentAnimation = animation;
279 
280  paused = false;
281 
282  animationBuffer.resize(static_cast<size_t>(animation->duration) * 3 * 256 * 4);
283 
284  size_t currentRow = 0;
285 
286  for (float t = 0.f, inc = 1.f / animation->ticksPerSecond,
287  duration = animation->duration / animation->ticksPerSecond;
288  t < duration;
289  t += inc) {
290  time = t;
291  Update(0.f);
292 
293  for (size_t i = 0, size = boneData.size(); i < size; ++i) {
294  glm::mat4 transform = boneData[i].transform;
295 
296  glm::vec4 translate = transform[3];
297  transform[3] = glm::vec4(0.f, 0.f, 0.f, 1.f);
298 
299  glm::vec3 scale = glm::vec3(
300  glm::length(glm::vec3(transform[0][0], transform[0][1], transform[0][2])),
301  glm::length(glm::vec3(transform[1][0], transform[1][1], transform[1][2])),
302  glm::length(glm::vec3(transform[2][0], transform[2][1], transform[2][2]))
303  );
304 
305  transform[0][0] /= scale.x;
306  transform[0][1] /= scale.x;
307  transform[0][2] /= scale.x;
308  transform[1][0] /= scale.y;
309  transform[1][1] /= scale.y;
310  transform[1][2] /= scale.y;
311  transform[2][0] /= scale.z;
312  transform[2][1] /= scale.z;
313  transform[2][2] /= scale.z;
314 
315  glm::quat rotation = glm::quat_cast(transform);
316 
317  animationBuffer[(currentRow * 256 * 4) + i * 4] = translate.x;
318  animationBuffer[(currentRow * 256 * 4) + i * 4 + 1] = translate.y;
319  animationBuffer[(currentRow * 256 * 4) + i * 4 + 2] = translate.z;
320  animationBuffer[(currentRow * 256 * 4) + i * 4 + 3] = translate.w;
321 
322  animationBuffer[((currentRow + 1) * 256 * 4) + i * 4] = scale.x;
323  animationBuffer[((currentRow + 1) * 256 * 4) + i * 4 + 1] = scale.y;
324  animationBuffer[((currentRow + 1) * 256 * 4) + i * 4 + 2] = scale.z;
325 
326  animationBuffer[((currentRow + 2) * 256 * 4) + i * 4] = rotation.x;
327  animationBuffer[((currentRow + 2) * 256 * 4) + i * 4 + 1] = rotation.y;
328  animationBuffer[((currentRow + 2) * 256 * 4) + i * 4 + 2] = rotation.z;
329  animationBuffer[((currentRow + 2) * 256 * 4) + i * 4 + 3] = rotation.w;
330  }
331 
332  currentRow += 3;
333 
334  }
335 
336 #ifdef USING_VULKAN
337  animation->texture = eastl::shared_ptr<VulkanTexture>(new VulkanTexture(256, static_cast<int>(animation->duration * 3.f)));
338  animation->texture->CreateTextureWithData(reinterpret_cast<stbi_uc*>(animationBuffer.data()), false, TextureDataSize::S_INT, true);
339 
340  VkSamplerCreateInfo samplerInfo = {};
341  samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
342  samplerInfo.magFilter = VK_FILTER_NEAREST;
343  samplerInfo.minFilter = VK_FILTER_NEAREST;
344  samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
345  samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
346  samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
347  samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
348  samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
349  samplerInfo.anisotropyEnable = VK_FALSE;
350  samplerInfo.compareEnable = VK_FALSE;
351  samplerInfo.unnormalizedCoordinates = VK_TRUE;
352 
353  eastl::static_pointer_cast<VulkanTexture, Texture>(animation->texture)->SetSampler(samplerInfo);
354 #endif
355 #ifdef USING_OPENGL
356  animation->texture = eastl::shared_ptr<OpenGLTexture>(new OpenGLTexture(256, static_cast<int>(animation->duration * 3.f)));
357  animation->texture->CreateTextureWithData(reinterpret_cast<stbi_uc*>(animationBuffer.data()), false, TextureDataSize::S_INT, true);
358 #endif
359 
360  }
361 
362  }
363  else {
364  std::cout << "[WARNING] No animations detected in file" << std::endl;
365  }
366  }
367 
368 
370  {
371  for each (eastl::pair<eastl::string, Bone_t*> bone in boneMap)
372  {
373  delete bone.second;
374  }
375  for (size_t i = 0, size = animations.size(); i < size; ++i) {
376  animations[i]->texture.reset();
377  delete animations[i];
378  }
379  }
380 
381  eastl::vector<eastl::string> Skeleton::GetAnimations()
382  {
383  eastl::vector<eastl::string> names;
384  for each (eastl::pair<eastl::string, size_t> animation in animationMap)
385  {
386  names.push_back(animation.first);
387  }
388  return names;
389  }
390 
391  void Skeleton::SetAnimation(eastl::string animation, bool resetTime)
392  {
393  eastl::map<eastl::string, size_t>::iterator it = animationMap.find(animation);
394 
395  if (it != animationMap.end() && it->second < animations.size()) {
396  currentAnimation = animations[it->second];
397  }
398  else {
399  currentAnimation = nullptr;
400  }
401 
402  if (resetTime)
403  time = 0.f;
404  }
405 
407  {
410  }
411 
413  {
414  }
415 
417  {
418  glm::vec3 scale;
419 
421 
422  if (node.scalingKeys.size() == 1) {
423  scale = node.scalingKeys[0].scale;
424  }
425  else {
426  size_t frameIndex = 0;
427  for (size_t i = 0, size = node.scalingKeys.size(); i < size - 1; ++i) {
428  if (time < node.scalingKeys[i + 1].time) {
429  frameIndex = i;
430  break;
431  }
432  }
433 
434  AnimationScalingKey_t currFrame = node.scalingKeys[frameIndex];
435  AnimationScalingKey_t nextFrame;
436  if (frameIndex + 1 == node.scalingKeys.size()) {
437  nextFrame = node.scalingKeys[frameIndex];
438  }
439  else {
440  nextFrame = node.scalingKeys[frameIndex + 1];
441  }
442 
443  float delta = (time - currFrame.time) / (nextFrame.time - currFrame.time);
444 
445  delta = fmaxf(0.f, fminf(delta, 1.f));
446 
447  scale = glm::mix(currFrame.scale, nextFrame.scale, delta);
448  }
449  return glm::scale(glm::mat4(), scale);
450  }
451 
453  {
454  glm::quat rotation;
455 
457 
458  if (node.rotationKeys.size() == 1) {
459  rotation = node.rotationKeys[0].rotation;
460  }
461  else {
462  size_t frameIndex = 0;
463  for (size_t i = 0, size = node.rotationKeys.size(); i < size - 1; ++i) {
464  if (time < node.rotationKeys[i + 1].time) {
465  frameIndex = i;
466  break;
467  }
468  }
469 
470  AnimationRotationKey_t currFrame = node.rotationKeys[frameIndex];
471  AnimationRotationKey_t nextFrame;
472  if (frameIndex + 1 == node.rotationKeys.size()) {
473  nextFrame = node.rotationKeys[frameIndex];
474  }
475  else {
476  nextFrame = node.rotationKeys[frameIndex + 1];
477  }
478 
479  float delta = (time - currFrame.time) / (nextFrame.time - currFrame.time);
480 
481  delta = fmaxf(0.f, fminf(delta, 1.f));
482 
483  rotation = glm::lerp(currFrame.rotation, nextFrame.rotation, delta);
484 
485  }
486 
487  return glm::mat4_cast(rotation);
488  }
489 
491  {
492  glm::vec3 position;
493 
495 
496  if (node.positionKeys.size() == 1) {
497  position = node.positionKeys[0].position;
498  }
499  else {
500  size_t frameIndex = 0;
501  for (size_t i = 0, size = node.positionKeys.size(); i < size - 1; ++i) {
502  if (time < node.positionKeys[i + 1].time) {
503  frameIndex = i;
504  break;
505  }
506  }
507 
508  AnimationPositionKey_t currFrame = node.positionKeys[frameIndex];
509  AnimationPositionKey_t nextFrame;
510  if (frameIndex + 1 == node.positionKeys.size()) {
511  nextFrame = node.positionKeys[frameIndex];
512  }
513  else {
514  nextFrame = node.positionKeys[frameIndex + 1];
515  }
516 
517  float delta = (time - currFrame.time) / (nextFrame.time - currFrame.time);
518 
519  delta = fmaxf(0.f, fminf(delta, 1.f));
520 
521  position = glm::mix(currFrame.position, nextFrame.position, delta);
522  }
523  return glm::translate(glm::mat4(), position);
524  }
525 
526  float Skeleton::GetAnimationDuration(size_t animation)
527  {
528  if (animation < animations.size()) {
529  return animations[animation]->duration / animations[animation]->ticksPerSecond;
530  }
531  else {
532  return 0.f;
533  }
534 
535  }
536 
537  void Skeleton::Update(float deltaTime)
538  {
539  if (paused)
540  return;
541 
542  time += deltaTime;
543 
544  if (looping)
546 
547  if (currentAnimation != nullptr) {
548 
549  for (size_t i = 0, size = currentAnimation->nodes.size(); i < size; ++i) {
550  Bone_t* bone = currentAnimation->nodes[i].bone;
551 
555  }
556 
557  }
558  else {
559  for each (eastl::pair<eastl::string, Bone_t*> bone in boneMap)
560  {
561  bone.second->transform = bone.second->defaultTransform;
562  }
563  }
564 
566  }
567 
569  {
570  return animated;
571  }
572 
574  {
575  if (animation < animations.size()) {
576  return animations[animation]->texture.get();
577  }
578  else {
579  return nullptr;
580  }
581  }
582 
583  size_t Skeleton::GetAnimationIndex(eastl::string animation)
584  {
585  eastl::map<eastl::string, size_t>::iterator it = animationMap.find(animation);
586 
587  if (it != animationMap.end() && it->second < animations.size()) {
588  return it->second;
589  }
590  else {
591  return -1;
592  }
593  }
594 
595  float Skeleton::GetAnimationTicksPerSecond(size_t animation)
596  {
597  if (animation < animations.size()) {
598  return animations[animation]->ticksPerSecond;
599  }
600  else {
601  return 0.f;
602  }
603  }
604 
605  eastl::map<eastl::string, Skeleton::Bone_t*> Skeleton::GetBoneMap()
606  {
607  return boneMap;
608  }
609 
611  {
612  return rootBone;
613  }
614 
615  void Skeleton::SetName(eastl::string name)
616  {
617  this->name = name;
618  }
619 
620  eastl::string Skeleton::GetName()
621  {
622  return name;
623  }
624 
625  void Skeleton::ReadBones(Bone_t * bone, aiNode * node)
626  {
627  bone->childBones.resize(static_cast<size_t>(node->mNumChildren));
628 
629  bone->name = eastl::string(node->mName.C_Str());
630 
631  bone->node = node;
632 
633  bone->boneDataIndex = static_cast<int>(boneMap.size());
634 
635  boneData[bone->boneDataIndex].transform = TransformToMat4(node->mTransformation);
636 
637  bone->transform = TransformToMat4(node->mTransformation);
638  bone->defaultTransform = bone->transform;
639 
640  boneMap[bone->name] = bone;
641 
642  for (size_t i = 0, size = bone->childBones.size(); i < size; ++i) {
643  bone->childBones[i] = new Bone_t;
644  bone->childBones[i]->parent = bone;
645  bone->childBones[i]->boneDataIndex = -1;
646  ReadBones(bone->childBones[i], node->mChildren[i]);
647  }
648  }
649 
651  {
652  for (size_t i = 0, size = bone->childBones.size(); i < size; ++i) {
653  DestroyBone(bone->childBones[i]);
654  }
655  delete bone;
656  }
657 
658  void Skeleton::SetBoneTransform(eastl::string bone, glm::mat4 transform)
659  {
660  eastl::map<eastl::string, Bone_t*>::iterator it = boneMap.find(bone);
661  if (it != boneMap.end()) {
662  SetBoneTransform(it->second, transform);
663  }
664  }
665 
666  void Skeleton::SetBoneTransform(Bone_t * bone, glm::mat4 transform)
667  {
668  bone->transform = transform;
669  }
670 
672  {
673  if (bone->parent != nullptr) {
674  boneData[bone->boneDataIndex].transform = boneData[bone->parent->boneDataIndex].transform * bone->transform;
675  }
676  else {
677  boneData[bone->boneDataIndex].transform = bone->transform;
678  }
679 
680  for (size_t i = 0, size = bone->childBones.size(); i < size; ++i) {
682  }
683  }
684 
685  glm::mat4 Skeleton::TransformToMat4(aiMatrix4x4 transform) {
686  return glm::mat4(transform.a1, transform.b1, transform.c1, transform.d1,
687  transform.a2, transform.b2, transform.c2, transform.d2,
688  transform.a3, transform.b3, transform.c3, transform.d3,
689  transform.a4, transform.b4, transform.c4, transform.d4);
690  }
691 
692 }
This object is used to store information regarding a texture. NOTE: Only the resource manager is allo...
Definition: Texture.hpp:23
struct Bone * parent
Definition: Skeleton.hpp:102
Texture * GetAnimationData(size_t animation)
Returns a texture containing the animation snapshots for the current animation.
Definition: Skeleton.cpp:573
eastl::string name
Definition: Skeleton.hpp:97
size_t GetAnimationIndex(eastl::string animation)
Returns a texture containing the animation snapshots for the current animation.
Definition: Skeleton.cpp:583
eastl::vector< struct Bone * > childBones
Definition: Skeleton.hpp:104
eastl::vector< AnimationScalingKey_t > scalingKeys
Definition: Skeleton.hpp:166
glm::mat4 TransformToMat4(aiMatrix4x4 transform)
Definition: Skeleton.cpp:685
eastl::vector< BoneData_t > boneData
Definition: Skeleton.hpp:173
Bone_t * GetRootBone()
Returns the root bone of the skeleton.
Definition: Skeleton.cpp:610
void UpdateBoneTreeTransformData()
Definition: Skeleton.cpp:406
size_t currentAnimationIndex
Definition: Skeleton.hpp:183
eastl::map< eastl::string, Bone_t * > boneMap
Definition: Skeleton.hpp:193
void SetAnimation(eastl::string animation, bool resetTime)
Sets the current animation of the mesh.
Definition: Skeleton.cpp:391
const aiScene * scene
Definition: Skeleton.hpp:179
eastl::vector< Animation_t * > animations
Definition: Skeleton.hpp:177
void UpdateBoneTransformData(Bone_t *bone)
Definition: Skeleton.cpp:671
eastl::vector< AnimationPositionKey_t > positionKeys
Definition: Skeleton.hpp:164
glm::mat4 defaultTransform
Definition: Skeleton.hpp:100
glm::mat4 InterpolateRotation(float time, AnimationNode_t node)
Definition: Skeleton.cpp:452
bool HasAnimations()
Whether or not any animations have been loaded.
Definition: Skeleton.cpp:568
void DestroyBone(Bone_t *bone)
Definition: Skeleton.cpp:650
float GetAnimationDuration(size_t animation)
Returns the duration of a single loop of the animation.
Definition: Skeleton.cpp:526
void SetName(eastl::string name)
Sets the name of the skeleton.
Definition: Skeleton.cpp:615
Bone_t * rootBone
Definition: Skeleton.hpp:171
float GetAnimationTicksPerSecond(size_t animation)
Returns the number of animation ticks per second. This is equal to the number of animation snapshots ...
Definition: Skeleton.cpp:595
void SetBoneTransform(eastl::string bone, glm::mat4 transform)
Definition: Skeleton.cpp:658
Skeleton(const aiScene *scene)
Creates a new animation data object, loading in the animation data from the provided scene...
Definition: Skeleton.cpp:17
eastl::shared_ptr< Texture > texture
Definition: Skeleton.hpp:140
eastl::string GetName()
Returns the name of the skeleton (normally the path).
Definition: Skeleton.cpp:620
eastl::map< eastl::string, size_t > animationMap
Definition: Skeleton.hpp:175
void ReadBones(Bone_t *bone, aiNode *node)
Definition: Skeleton.cpp:625
struct Engine::Skeleton::Animation Animation_t
A structure containing information a bone.
Definition: Skeleton.hpp:96
struct Engine::Skeleton::Bone Bone_t
A structure containing information a bone.
virtual void UpdateBoneBuffers()
Definition: Skeleton.cpp:412
aiAnimBehaviour preAnimBehaviour
Definition: Skeleton.hpp:167
eastl::vector< AnimationRotationKey_t > rotationKeys
Definition: Skeleton.hpp:165
glm::mat4 InterpolateScale(float time, AnimationNode_t node)
Definition: Skeleton.cpp:416
void LoadAnimationSet(const aiScene *scene, eastl::vector< eastl::string > names={})
Loads in animation data form the provided scene. If the animation data does not match the skeleton of...
Definition: Skeleton.cpp:196
Animation_t * currentAnimation
Definition: Skeleton.hpp:181
eastl::vector< struct AnimationNode > nodes
Definition: Skeleton.hpp:137
eastl::string name
Definition: Skeleton.hpp:195
virtual ~Skeleton()
Destroys the Data, cleaning up the bone tree.
Definition: Skeleton.cpp:369
glm::mat4 InterpolatePosition(float time, AnimationNode_t node)
Definition: Skeleton.cpp:490
aiAnimBehaviour postAnimBehaviour
Definition: Skeleton.hpp:168
eastl::map< eastl::string, Bone_t * > GetBoneMap()
Returns a map that uses the name of a bone as key to return the corresponding bone.
Definition: Skeleton.cpp:605
eastl::vector< eastl::string > GetAnimations()
Returns a list of the loaded animations as a vector of names. Use these names to load a specific anim...
Definition: Skeleton.cpp:381
void Update(float deltaTime)
Definition: Skeleton.cpp:537