Animation optimization

This commit is contained in:
Teejoon
2016-03-13 19:01:30 +01:00
parent a9d5c5d9d2
commit 5aaefc6e53
5 changed files with 34 additions and 37 deletions
+4 -1
View File
@@ -20,11 +20,14 @@ public:
, Parent(parent) , Parent(parent)
, Name(name) , Name(name)
, OffsetMatrix(offsetMatrix) , OffsetMatrix(offsetMatrix)
{ } {
BindTransformMatrix = glm::inverse(offsetMatrix);
}
std::string Name; std::string Name;
glm::mat4 OffsetMatrix; glm::mat4 OffsetMatrix;
int ID; int ID;
glm::mat4 BindTransformMatrix;
Bone* Parent; Bone* Parent;
std::vector<Bone*> Children; std::vector<Bone*> Children;
@@ -36,12 +36,10 @@ void main()
{ {
mat4 boneTransform = mat4(1); mat4 boneTransform = mat4(1);
if(BoneWeights[0] > 0.0f){
boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])]
+ BoneWeights[1] * Bones[int(BoneIndices[1])] + BoneWeights[1] * Bones[int(BoneIndices[1])]
+ BoneWeights[2] * Bones[int(BoneIndices[2])] + BoneWeights[2] * Bones[int(BoneIndices[2])]
+ BoneWeights[3] * Bones[int(BoneIndices[3])]; + BoneWeights[3] * Bones[int(BoneIndices[3])];
}
gl_Position = PVM*boneTransform * vec4(Position, 1.0); gl_Position = PVM*boneTransform * vec4(Position, 1.0);
@@ -17,12 +17,10 @@ out VertexData{
void main() void main()
{ {
mat4 boneTransform = mat4(1); mat4 boneTransform = mat4(1);
if(BoneWeights[0] > 0.0f){
boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])]
+ BoneWeights[1] * Bones[int(BoneIndices[1])] + BoneWeights[1] * Bones[int(BoneIndices[1])]
+ BoneWeights[2] * Bones[int(BoneIndices[2])] + BoneWeights[2] * Bones[int(BoneIndices[2])]
+ BoneWeights[3] * Bones[int(BoneIndices[3])]; + BoneWeights[3] * Bones[int(BoneIndices[3])];
}
gl_Position = PVM*boneTransform * vec4(Position, 1.0); gl_Position = PVM*boneTransform * vec4(Position, 1.0);
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
@@ -15,12 +15,10 @@ out VertexData{
void main() void main()
{ {
mat4 boneTransform = mat4(1); mat4 boneTransform = mat4(1);
if(BoneWeights[0] > 0.0f){
boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])]
+ BoneWeights[1] * Bones[int(BoneIndices[1])] + BoneWeights[1] * Bones[int(BoneIndices[1])]
+ BoneWeights[2] * Bones[int(BoneIndices[2])] + BoneWeights[2] * Bones[int(BoneIndices[2])]
+ BoneWeights[3] * Bones[int(BoneIndices[3])]; + BoneWeights[3] * Bones[int(BoneIndices[3])];
}
gl_Position = PVM * boneTransform * vec4(Position, 1.0); gl_Position = PVM * boneTransform * vec4(Position, 1.0);
Output.TextureCoordinate = TextureCoords; Output.TextureCoordinate = TextureCoords;
+30 -30
View File
@@ -33,33 +33,33 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim
PoseData poseData; PoseData poseData;
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID); const std::vector<Animation::Keyframe>& boneKeyFrames = animation->JointAnimations.at(bone->ID);
Animation::Keyframe currentFrame; const Animation::Keyframe* currentFrame;
Animation::Keyframe nextFrame; const Animation::Keyframe* nextFrame;
if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone
for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame
if (time >= boneKeyFrames.at(index).Time) { if (time >= boneKeyFrames.at(index).Time) {
currentFrame = boneKeyFrames.at(index); currentFrame = &boneKeyFrames.at(index);
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); nextFrame = &boneKeyFrames.at((index + 1) % boneKeyFrames.size());
break; break;
} }
} }
float progress; float progress;
if (nextFrame.Index == 0) { if (nextFrame->Index == 0) {
nextFrame = currentFrame; nextFrame = currentFrame;
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); progress = (time - currentFrame->Time) / (animation->Duration - currentFrame->Time);
} else { } else {
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); progress = (time - currentFrame->Time) / (nextFrame->Time - currentFrame->Time);
} }
progress = glm::clamp(progress, 0.0f, 1.0f); progress = glm::clamp(progress, 0.0f, 1.0f);
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; const Animation::Keyframe::BoneProperty& currentBoneProperty = currentFrame->BoneProperties;
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; const Animation::Keyframe::BoneProperty& nextBoneProperty = nextFrame->BoneProperties;
glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
glm::quat rotation = glm::normalize(glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress)); glm::quat rotation = glm::normalize(glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress));
@@ -77,10 +77,10 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim
boneMatrices[bone->ID] = poseData; boneMatrices[bone->ID] = poseData;
} else { // 1 keyframes for the current bone } else { // 1 keyframes for the current bone
currentFrame = boneKeyFrames.at(0); currentFrame = &boneKeyFrames.at(0);
poseData.Translation = currentFrame.BoneProperties.Position; poseData.Translation = currentFrame->BoneProperties.Position;
poseData.Orientation = currentFrame.BoneProperties.Rotation; poseData.Orientation = currentFrame->BoneProperties.Rotation;
poseData.Scale = currentFrame.BoneProperties.Scale; poseData.Scale = currentFrame->BoneProperties.Scale;
boneMatrices[bone->ID] = poseData; boneMatrices[bone->ID] = poseData;
} }
} }
@@ -117,33 +117,33 @@ Skeleton::PoseData Skeleton::GetAdditiveBonePose(const Bone* bone, const Animati
glm::vec3 scale = glm::vec3(1); glm::vec3 scale = glm::vec3(1);
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID); const std::vector<Animation::Keyframe>& boneKeyFrames = animation->JointAnimations.at(bone->ID);
Animation::Keyframe currentFrame; const Animation::Keyframe* currentFrame;
Animation::Keyframe nextFrame; const Animation::Keyframe* nextFrame;
if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone
for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame
if (time >= boneKeyFrames.at(index).Time) { if (time >= boneKeyFrames.at(index).Time) {
currentFrame = boneKeyFrames.at(index); currentFrame = &boneKeyFrames.at(index);
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); nextFrame = &boneKeyFrames.at((index + 1) % boneKeyFrames.size());
break; break;
} }
} }
float progress; float progress;
if (nextFrame.Index == 0) { if (nextFrame->Index == 0) {
nextFrame = currentFrame; nextFrame = currentFrame;
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); progress = (time - currentFrame->Time) / (animation->Duration - currentFrame->Time);
} else { } else {
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); progress = (time - currentFrame->Time) / (nextFrame->Time - currentFrame->Time);
} }
progress = glm::clamp(progress, 0.0f, 1.0f); progress = glm::clamp(progress, 0.0f, 1.0f);
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; const Animation::Keyframe::BoneProperty& currentBoneProperty = currentFrame->BoneProperties;
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; const Animation::Keyframe::BoneProperty& nextBoneProperty = nextFrame->BoneProperties;
position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
@@ -151,10 +151,10 @@ Skeleton::PoseData Skeleton::GetAdditiveBonePose(const Bone* bone, const Animati
} else { // 1 keyframes for the current bone } else { // 1 keyframes for the current bone
currentFrame = boneKeyFrames.at(0); currentFrame = &boneKeyFrames.at(0);
position = currentFrame.BoneProperties.Position; position = currentFrame->BoneProperties.Position;
rotation = currentFrame.BoneProperties.Rotation; rotation = currentFrame->BoneProperties.Rotation;
scale = currentFrame.BoneProperties.Scale; scale = currentFrame->BoneProperties.Scale;
} }
} }
@@ -270,10 +270,10 @@ void Skeleton::AccumulateFinalPose(std::map<int, glm::mat4>& boneMatrices, std::
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
} else { } else {
if (bone->Parent) { if (bone->Parent) {
boneMatrix = parentMatrix * (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix); boneMatrix = parentMatrix * bone->BindTransformMatrix * bone->Parent->OffsetMatrix;
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
} else { } else {
boneMatrix = glm::inverse(bone->OffsetMatrix); boneMatrix = bone->BindTransformMatrix;
boneMatrices[bone->ID] = parentMatrix; boneMatrices[bone->ID] = parentMatrix;
} }
} }