-
Notifications
You must be signed in to change notification settings - Fork 4
/
SkeletalMeshComponent.cpp
87 lines (76 loc) · 2.07 KB
/
SkeletalMeshComponent.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
75
76
77
78
79
80
81
82
83
84
85
86
87
// Ahmed S. Tolba 2015-2018
#include "SkeletalMeshComponent.h"
#include "Shader.h"
#include "Mesh.h"
#include "Actor.h"
#include "Game.h"
#include "Renderer.h"
#include "Texture.h"
#include "VertexArray.h"
#include "Animation.h"
#include "Skeleton.h"
SkeletalMeshComponent::SkeletalMeshComponent(Actor* owner)
:MeshComponent(owner, true)
,mSkeleton(nullptr)
{
}
void SkeletalMeshComponent::Draw(Shader* shader)
{
if (mMesh)
{
// Set the world transform
shader->SetMatrixUniform("uWorldTransform",
mOwner->GetWorldTransform());
// Set the matrix palette
shader->SetMatrixUniforms("uMatrixPalette", &mPalette.mEntry[0],
MAX_SKELETON_BONES);
// Set specular power
shader->SetFloatUniform("uSpecPower", mMesh->GetSpecPower());
// Set the active texture
Texture* t = mMesh->GetTexture(mTextureIndex);
if (t)
{
t->SetActive();
}
// Set the mesh's vertex array as active
VertexArray* va = mMesh->GetVertexArray();
va->SetActive();
// Draw
glDrawElements(GL_TRIANGLES, va->GetNumIndices(), GL_UNSIGNED_INT, nullptr);
}
}
void SkeletalMeshComponent::Update(float deltaTime)
{
if (mAnimation && mSkeleton)
{
mAnimTime += deltaTime * mAnimPlayRate;
// Wrap around anim time if past duration
while (mAnimTime > mAnimation->GetDuration())
{
mAnimTime -= mAnimation->GetDuration();
}
// Recompute matrix palette
ComputeMatrixPalette();
}
}
float SkeletalMeshComponent::PlayAnimation(const Animation* anim, float playRate)
{
mAnimation = anim;
mAnimTime = 0.0f;
mAnimPlayRate = playRate;
if (!mAnimation) { return 0.0f; }
ComputeMatrixPalette();
return mAnimation->GetDuration();
}
void SkeletalMeshComponent::ComputeMatrixPalette()
{
const std::vector<Matrix4>& globalInvBindPoses = mSkeleton->GetGlobalInvBindPoses();
std::vector<Matrix4> currentPoses;
mAnimation->GetGlobalPoseAtTime(currentPoses, mSkeleton, mAnimTime);
// Setup the palette for each bone
for (size_t i = 0; i < mSkeleton->GetNumBones(); i++)
{
// Global inverse bind pose matrix times current pose matrix
mPalette.mEntry[i] = globalInvBindPoses[i] * currentPoses[i];
}
}