BoneAttachments now working and BlendTrees are created in the AnimationSystem

This commit is contained in:
viktorljung
2016-02-26 10:17:47 +01:00
parent c97d0d9381
commit af034673f6
13 changed files with 308 additions and 269 deletions
+66 -23
View File
@@ -1,66 +1,109 @@
#include "Rendering/AnimationSystem.h"
void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt)
AnimationSystem::AnimationSystem(SystemParams params)
: System(params)
{
EntityWrapper parent = entity.FirstParentWithComponent("Model");
Model* model;
try {
model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]);
} catch (const std::exception&) {
}
void AnimationSystem::Update(double dt)
{
UpdateAnimations(dt);
CreateBlendTrees();
}
void AnimationSystem::CreateBlendTrees()
{
auto modelComponents = m_World->GetComponents("Model");
if (modelComponents == nullptr) {
return;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
if (skeleton == nullptr) {
for (auto& modelC : *modelComponents) {
EntityWrapper entity = EntityWrapper(m_World, modelC.EntityID);
Model* model;
try {
model = ResourceManager::Load<::Model, true>(entity["Model"]["Resource"]);
} catch (const std::exception&) {
continue;;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
if (skeleton == nullptr) {
continue;
}
skeleton->BlendTrees[entity] = std::shared_ptr<BlendTree>(new BlendTree(entity, skeleton));
}
}
void AnimationSystem::UpdateAnimations(double dt)
{
auto animationComponents = m_World->GetComponents("Animation");
if(animationComponents == nullptr) {
return;
}
for (int i = 1; i <= 1; i++) {
const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]);
for (auto& animationC : *animationComponents) {
EntityWrapper entity = EntityWrapper(m_World, animationC.EntityID);
EntityWrapper parent = entity.FirstParentWithComponent("Model");
Model* model;
try {
model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]);
} catch (const std::exception&) {
return;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
if (skeleton == nullptr) {
return;
}
const Skeleton::Animation* animation = skeleton->GetAnimation(animationC["AnimationName"]);
if (animation == nullptr) {
continue;;
}
double animationSpeed = (double)animationComponent["Speed"];
double animationSpeed = (double)animationC["Speed"];
if (animationSpeed != 0.0) {
double nextTime = (double)animationComponent["Time"] + animationSpeed * dt;
double nextTime = (double)animationC["Time"] + animationSpeed * dt;
if (!(bool)animationComponent["Loop"]) {
if (!(bool)animationC["Loop"]) {
if (nextTime > animation->Duration) {
nextTime = animation->Duration;
Events::AnimationComplete e;
e.Entity = entity;
e.Name = (std::string)animationComponent["AnimationName"];
e.Name = (std::string)animationC["AnimationName"];
m_EventBroker->Publish(e);
} else if (nextTime < 0) {
Events::AnimationComplete e;
e.Entity = entity;
e.Name = (std::string)animationComponent["AnimationName"];
e.Name = (std::string)animationC["AnimationName"];
m_EventBroker->Publish(e);
nextTime = 0;
}
(double&)animationComponent["Speed"] = 0.0;
(double&)animationC["Speed"] = 0.0;
} else {
if (nextTime > animation->Duration) {
Events::AnimationComplete e;
e.Entity = entity;
e.Name = (std::string)animationComponent["AnimationName"];
e.Name = (std::string)animationC["AnimationName"];
m_EventBroker->Publish(e);
while(nextTime > animation->Duration) {
while (nextTime > animation->Duration) {
nextTime -= animation->Duration;
}
} else if (nextTime < 0) {
Events::AnimationComplete e;
e.Entity = entity;
e.Name = (std::string)animationComponent["AnimationName"];
e.Name = (std::string)animationC["AnimationName"];
m_EventBroker->Publish(e);
while (nextTime < 0) {
@@ -69,8 +112,8 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
}
}
(double&)animationComponent["Time"] = nextTime;
(double&)animationC["Time"] = nextTime;
}
}
}
}
+12 -1
View File
@@ -76,6 +76,17 @@ BlendTree::~BlendTree()
}
}
glm::mat4 BlendTree::GetBoneTransform(int boneID)
{
if(m_FinalBoneTransforms.find(boneID) != m_FinalBoneTransforms.end()) {
return m_FinalBoneTransforms.at(boneID);
} else {
return glm::mat4(1);
}
}
void BlendTree::PrintTree()
{
Node* currentNode = m_Root;
@@ -213,7 +224,7 @@ std::vector<glm::mat4> BlendTree::AccumulateFinalPose()
std::map<int, glm::mat4> pose;
Blend(pose);
finalPose = m_Skeleton->GetFinalPose(pose);
m_Skeleton->GetFinalPose(pose, finalPose, m_FinalBoneTransforms);
return finalPose;
}
+24 -53
View File
@@ -8,10 +8,13 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
return;
}
auto parent = entity.FirstParentWithComponent("Animation");
if (!parent.HasComponent("Model")) {
auto parent = entity.FirstParentWithComponent("Model");
if(!parent.Valid()) {
return;
}
Model* model;
try {
model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]);
@@ -35,61 +38,29 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
return;
}
/* std::vector<::Skeleton::AnimationData> Animations;
::Skeleton::AnimationOffset AnimationOffset;
glm::mat4 boneTransform;
if (skeleton->BlendTrees.find(parent) != skeleton->BlendTrees.end()) {
if (parent.HasComponent("Animation")) {
::Skeleton::AnimationData animationData;
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["Animation"]["AnimationName"]);
if (animationData.animation != nullptr) {
animationData.time = (double)parent["Animation"]["Time"];
Animations.push_back(animationData);
}
}
if (parent.HasComponent("AnimationOffset")) {
AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["AnimationOffset"]["AnimationName"]);
AnimationOffset.time = (double)parent["AnimationOffset"]["Time"];
glm::mat4 boneTransform = skeleton->BlendTrees.at(parent)->GetBoneTransform(id);
if(AnimationOffset.animation != nullptr) {
boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, AnimationOffset, glm::mat4(1));
} else {
boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, glm::mat4(1));
}
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(boneTransform, scale, rotation, translation, skew, perspective);
glm::vec3 angles = glm::vec3(-glm::pitch(rotation), -glm::yaw(rotation), -glm::roll(rotation));
} else {
boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, glm::mat4(1));
if ((bool)entity["BoneAttachment"]["InheritPosition"]) {
(glm::vec3&)entity["Transform"]["Position"] = translation + (glm::vec3)entity["BoneAttachment"]["PositionOffset"];
}
if ((bool)entity["BoneAttachment"]["InheritOrientation"]) {
(glm::vec3&)entity["Transform"]["Orientation"] = angles + (glm::vec3)entity["BoneAttachment"]["OrientationOffset"];
}
if ((bool)entity["BoneAttachment"]["InheritScale"]) {
(glm::vec3&)entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"];
}
}
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(boneTransform, scale, rotation, translation, skew, perspective);
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]);
angles.z = atan2(boneTransform[0][1], boneTransform[0][0]);
} 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"];
}
if ((bool)entity["BoneAttachment"]["InheritOrientation"]) {
(glm::vec3&)entity["Transform"]["Orientation"] = angles + (glm::vec3)entity["BoneAttachment"]["OrientationOffset"];
}
if ((bool)entity["BoneAttachment"]["InheritScale"]) {
(glm::vec3&)entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"];
}*/
}
+40 -29
View File
@@ -337,9 +337,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene);
//bind textures
BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob);
std::vector<glm::mat4> frameBones;
frameBones = explosionEffectJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (explosionEffectJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = explosionEffectJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_ExplosionEffectProgram->Bind();
GLERROR("Bind ExplosionEffect program");
@@ -360,10 +362,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
//bind textures
BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob);
GLERROR("asdasd");
std::vector<glm::mat4> frameBones;
frameBones = explosionEffectJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (explosionEffectJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = explosionEffectJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_ExplosionEffectSplatMapProgram->Bind();
GLERROR("Bind ExplosionEffectSplatMap program");
@@ -401,10 +404,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
BindModelUniforms(forwardSkinnedHandle, modelJob, scene);
//bind textures
BindModelTextures(forwardSkinnedHandle, modelJob);
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_ForwardPlusProgram->Bind();
GLERROR("Bind ForwardPlusProgram");
@@ -425,10 +430,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
//bind textures
BindModelTextures(forwardSplatMapSkinnedHandle, modelJob);
GLERROR("asdasd");
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_ForwardPlusSplatMapProgram->Bind();
GLERROR("Bind SplatMap program");
@@ -469,9 +475,11 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::list<std::shared_ptr<RenderJo
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
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;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_ShieldToStencilProgram->Bind();
GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle();
@@ -523,10 +531,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
continue;
}
std::vector<glm::mat4> frameBones;
frameBones = explosionEffectJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (explosionEffectJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = explosionEffectJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
if (GLERROR("Animation")) {
continue;
}
@@ -558,10 +567,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
//bind textures
BindModelTextures(forwardHandle ,modelJob);
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
//draw
glBindVertexArray(modelJob->Model->VAO);
@@ -590,10 +600,11 @@ void DrawFinalPass::DrawToDepthBuffer(std::list<std::shared_ptr<RenderJob>>& job
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_FillDepthBufferProgram->Bind();
GLuint shaderHandle = m_FillDepthBufferProgram->GetHandle();
+12 -12
View File
@@ -100,12 +100,10 @@ void PickingPass::Draw(RenderScene& scene)
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_PickingProgram->Bind();
@@ -155,9 +153,11 @@ void PickingPass::Draw(RenderScene& scene)
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_PickingProgram->Bind();
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
@@ -206,9 +206,11 @@ void PickingPass::Draw(RenderScene& scene)
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_PickingProgram->Bind();
@@ -261,12 +263,10 @@ void PickingPass::Draw(RenderScene& scene)
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
if (modelJob->BlendTree != nullptr) {
std::vector<glm::mat4> frameBones;
frameBones = modelJob->BlendTree->GetFinalPose();
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
} else {
m_PickingProgram->Bind();
+7 -9
View File
@@ -94,7 +94,7 @@ void Skeleton::AdditiveBoneTransforms(const Animation* animation, double time, s
{
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
glm::mat4 refPose = GetAdditiveBonePose(bone, animation, 0.0);
glm::mat4 srcPose = GetAdditiveBonePose(bone, animation, time);
glm::mat4 srcPose = GetAdditiveBonePose(bone, animation, time + 1.0/60.0);
glm::mat4 boneMatrix = srcPose * glm::inverse(refPose);
boneMatrices[bone->ID] = boneMatrix;
}
@@ -335,21 +335,17 @@ std::map<int, glm::mat4> Skeleton::BlendPoseAdditive(const std::map<int, glm::ma
return finalPose;
}
std::vector<glm::mat4> Skeleton::GetFinalPose(std::map<int, glm::mat4>& boneMatrices)
void Skeleton::GetFinalPose(std::map<int, glm::mat4>& boneMatrices, std::vector<glm::mat4>& finalPose, std::map<int, glm::mat4>& boneTransforms)
{
std::vector<glm::mat4> finalPose;
AccumulateFinalPose(boneMatrices, RootBone, glm::mat4(1));
AccumulateFinalPose(boneMatrices, boneTransforms, RootBone, glm::mat4(1));
for(auto& b : boneMatrices) {
finalPose.push_back(b.second);
}
return finalPose;
}
void Skeleton::AccumulateFinalPose(std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
void Skeleton::AccumulateFinalPose(std::map<int, glm::mat4>& boneMatrices, std::map<int, glm::mat4>& boneTransforms, const Bone* bone, glm::mat4 parentMatrix)
{
glm::mat4 boneMatrix;
@@ -370,8 +366,10 @@ void Skeleton::AccumulateFinalPose(std::map<int, glm::mat4>& boneMatrices, const
}
}
boneTransforms[bone->ID] = boneMatrix;
for (auto &child : bone->Children) {
AccumulateFinalPose(boneMatrices, child, boneMatrix);
AccumulateFinalPose(boneMatrices, boneTransforms, child, boneMatrix);
}
}