Fixed BoneAttachment component and optimized animation code a bit
This commit is contained in:
@@ -47,7 +47,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
|
||||
|
||||
ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
||||
{
|
||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
||||
}
|
||||
|
||||
bool ComponentPool::KnowsEntity(EntityID ent)
|
||||
|
||||
@@ -24,7 +24,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]);
|
||||
|
||||
if (animation == nullptr) {
|
||||
return;
|
||||
continue;;
|
||||
}
|
||||
|
||||
double animationSpeed = (double)animationComponent["Speed" + std::to_string(i)];
|
||||
@@ -49,5 +49,32 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate bone transforms
|
||||
if (skeleton != nullptr) {
|
||||
std::vector<Skeleton::AnimationData> animations;
|
||||
if (entity.HasComponent("Animation")) {
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(entity["Animation"]["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)entity["Animation"]["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)entity["Animation"]["Weight" + std::to_string(i)];
|
||||
|
||||
animations.push_back(animationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent("AnimationOffset")) {
|
||||
Skeleton::AnimationOffset animationOffset;
|
||||
animationOffset.animation = skeleton->GetAnimation(entity["AnimationOffset"]["AnimationName"]);
|
||||
animationOffset.time = (double)entity["AnimationOffset"]["Time"];
|
||||
skeleton->CalculateFrameBones(animations, animationOffset);
|
||||
} else {
|
||||
skeleton->CalculateFrameBones(animations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1));
|
||||
glm::mat4 boneTransform = skeleton->GetBoneTransformSuper(id);
|
||||
//glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1));
|
||||
|
||||
glm::vec3 scale;
|
||||
glm::quat rotation;
|
||||
@@ -48,7 +49,9 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(boneTransform, scale, rotation, translation, skew, perspective);
|
||||
|
||||
glm::vec3 angles;
|
||||
glm::vec3 angles = glm::vec3(-glm::pitch(rotation), -glm::yaw(rotation), -glm::roll(rotation));
|
||||
/*
|
||||
|
||||
angles.y = asin(-boneTransform[0][2]);
|
||||
if (cos(angles.y) != 0) {
|
||||
angles.x = atan2(boneTransform[1][2], boneTransform[2][2]);
|
||||
@@ -56,7 +59,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
} else {
|
||||
angles.x = atan2(-boneTransform[2][0], boneTransform[1][1]);
|
||||
angles.z = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((bool)entity["BoneAttachment"]["InheritPosition"]) {
|
||||
(glm::vec3&)entity["Transform"]["Position"] = translation + (glm::vec3)entity["BoneAttachment"]["PositionOffset"];
|
||||
|
||||
@@ -328,11 +328,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
@@ -355,11 +351,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -400,11 +392,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindModelTextures(forwardSkinnedHandle, modelJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -428,11 +416,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindModelTextures(forwardSplatMapSkinnedHandle, modelJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -476,13 +460,8 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::list<std::shared_ptr<RenderJo
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
m_ShieldToStencilProgram->Bind();
|
||||
GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle();
|
||||
@@ -535,11 +514,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
if (GLERROR("Animation")) {
|
||||
@@ -574,11 +549,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
BindModelTextures(forwardHandle ,modelJob);
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
|
||||
@@ -610,11 +581,7 @@ void DrawFinalPass::DrawToDepthBuffer(std::list<std::shared_ptr<RenderJob>>& job
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -103,11 +103,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
@@ -160,11 +156,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_PickingProgram->Bind();
|
||||
@@ -215,11 +207,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -276,11 +264,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
|
||||
@@ -62,14 +62,14 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
}
|
||||
|
||||
// Only render children of a camera if that camera is currently active
|
||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||
continue;
|
||||
}
|
||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
||||
if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) {
|
||||
continue;
|
||||
}
|
||||
if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Model* model;
|
||||
try {
|
||||
|
||||
+157
-248
@@ -29,6 +29,32 @@ Skeleton::~Skeleton()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::CalculateFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
for (auto& b : Bones) {
|
||||
m_BoneLocalTransforms[b.first] = glm::mat4(1);
|
||||
m_BoneTransforms[b.first] = glm::mat4(1);
|
||||
}
|
||||
} else {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, RootBone, glm::mat4(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::CalculateFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0) {
|
||||
for (auto& b : Bones) {
|
||||
m_BoneLocalTransforms[b.first] = glm::mat4(1);
|
||||
m_BoneTransforms[b.first] = glm::mat4(1);
|
||||
}
|
||||
} else {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, RootBone, glm::mat4(1));
|
||||
}
|
||||
}
|
||||
|
||||
const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
{
|
||||
auto it = Animations.find(name);
|
||||
@@ -39,252 +65,10 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
/*
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
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
|
||||
if (time >= boneKeyFrames.at(index).Time) {
|
||||
currentFrame = boneKeyFrames.at(index);
|
||||
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float progress;
|
||||
|
||||
if(nextFrame.Index == 0) {
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
glm::vec3 positionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
positionInterp.x = 0;
|
||||
positionInterp.z = 0;
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
boneMatrix = parentMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
// LOG_INFO("%s Has no keyframe", bone->Name.c_str());
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
|
||||
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
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
|
||||
if (time >= boneKeyFrames.at(index).Time) {
|
||||
currentFrame = boneKeyFrames.at(index);
|
||||
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(JointTransforms.size() <= 0) {
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms)
|
||||
{
|
||||
if(jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
|
||||
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
@@ -363,10 +147,12 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
boneMatrix = parentMatrix *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix));
|
||||
|
||||
}
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
boneMatrix = offset * glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = parentMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -401,15 +187,138 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
} else {
|
||||
boneMatrix = parentMatrix * (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
}
|
||||
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix);
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
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
|
||||
if (time >= boneKeyFrames.at(index).Time) {
|
||||
currentFrame = boneKeyFrames.at(index);
|
||||
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (JointTransforms.size() <= 0) {
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
m_BoneLocalTransforms[bone->ID] = parentMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp));
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
if (jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user