Animation optimization
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user