SkeletalMeshComponent.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // ----------------------------------------------------------------
  2. // From Game Programming in C++ by Sanjay Madhav
  3. // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
  4. //
  5. // Released under the BSD License
  6. // See LICENSE in root directory for full details.
  7. // ----------------------------------------------------------------
  8. #include "SkeletalMeshComponent.h"
  9. #include "Shader.h"
  10. #include "Mesh.h"
  11. #include "Actor.h"
  12. #include "Game.h"
  13. #include "Renderer.h"
  14. #include "Texture.h"
  15. #include "VertexArray.h"
  16. #include "Animation.h"
  17. #include "Skeleton.h"
  18. SkeletalMeshComponent::SkeletalMeshComponent(Actor* owner)
  19. :MeshComponent(owner, true)
  20. ,mSkeleton(nullptr)
  21. {
  22. }
  23. void SkeletalMeshComponent::Draw(Shader* shader)
  24. {
  25. if (mMesh)
  26. {
  27. // Set the world transform
  28. shader->SetMatrixUniform("uWorldTransform",
  29. mOwner->GetWorldTransform());
  30. // Set the matrix palette
  31. shader->SetMatrixUniforms("uMatrixPalette", &mPalette.mEntry[0],
  32. MAX_SKELETON_BONES);
  33. // Set specular power
  34. shader->SetFloatUniform("uSpecPower", mMesh->GetSpecPower());
  35. // Set the active texture
  36. Texture* t = mMesh->GetTexture(mTextureIndex);
  37. if (t)
  38. {
  39. t->SetActive();
  40. }
  41. // Set the mesh's vertex array as active
  42. VertexArray* va = mMesh->GetVertexArray();
  43. va->SetActive();
  44. // Draw
  45. glDrawElements(GL_TRIANGLES, va->GetNumIndices(), GL_UNSIGNED_INT, nullptr);
  46. }
  47. }
  48. void SkeletalMeshComponent::Update(float deltaTime)
  49. {
  50. if (mAnimation && mSkeleton)
  51. {
  52. mAnimTime += deltaTime * mAnimPlayRate;
  53. // Wrap around anim time if past duration
  54. while (mAnimTime > mAnimation->GetDuration())
  55. {
  56. mAnimTime -= mAnimation->GetDuration();
  57. }
  58. // Recompute matrix palette
  59. ComputeMatrixPalette();
  60. }
  61. }
  62. float SkeletalMeshComponent::PlayAnimation(const Animation* anim, float playRate)
  63. {
  64. mAnimation = anim;
  65. mAnimTime = 0.0f;
  66. mAnimPlayRate = playRate;
  67. if (!mAnimation) { return 0.0f; }
  68. ComputeMatrixPalette();
  69. return mAnimation->GetDuration();
  70. }
  71. void SkeletalMeshComponent::ComputeMatrixPalette()
  72. {
  73. const std::vector<Matrix4>& globalInvBindPoses = mSkeleton->GetGlobalInvBindPoses();
  74. std::vector<Matrix4> currentPoses;
  75. mAnimation->GetGlobalPoseAtTime(currentPoses, mSkeleton, mAnimTime);
  76. // Setup the palette for each bone
  77. for (size_t i = 0; i < mSkeleton->GetNumBones(); i++)
  78. {
  79. // Global inverse bind pose matrix times current pose matrix
  80. mPalette.mEntry[i] = globalInvBindPoses[i] * currentPoses[i];
  81. }
  82. }