Added BoneAttachment component

This commit is contained in:
viktorljung
2016-01-27 17:14:16 +01:00
parent d12246833e
commit 8fc8d56ee1
13 changed files with 322 additions and 17 deletions
@@ -0,0 +1,29 @@
#ifndef BoneAttachmentSystem_h__
#define BoneAttachmentSystem_h__
#include "GLM.h"
#include "Common.h"
#include "Core/System.h"
#include "Core/ResourceManager.h"
#include "Rendering/Model.h"
#include "Rendering/Skeleton.h"
//Needs to be a higher orderlevel than AnimationSystem
class BoneAttachmentSystem : public PureSystem
{
public:
BoneAttachmentSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("BoneAttachment")
{
}
~BoneAttachmentSystem() { }
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) override;
private:
};
#endif
+7 -5
View File
@@ -82,17 +82,19 @@ public:
int GetBoneID(std::string name);
const Animation* GetAnimation(std::string name);
std::vector<glm::mat4> GetFrameBones(const Animation& animation, double time, bool noRootMotion = false);
void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix);
void PrintSkeleton();
const Animation* GetAnimation(std::string name);
std::vector<glm::mat4> GetFrameBones(const Animation& animation, double time, bool noRootMotion = false);
void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix);
void PrintSkeleton();
void PrintSkeleton(const Bone* parent, int depthCount);
std::map<std::string, Animation> Animations;
glm::mat4 GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix);
int GetKeyframe(const Animation& animation, double time);
private:
std::map<std::string, Bone*> m_BonesByName;
int GetKeyframe(const Animation& animation, double time);
};
#endif
+1
View File
@@ -24,4 +24,5 @@
<xs:include schemaLocation="Components/UniformScale.xsd"/>
<xs:include schemaLocation="Components/EditorWidget.xsd"/>
<xs:include schemaLocation="Components/Animation.xsd"/>
<xs:include schemaLocation="Components/BoneAttachment.xsd"/>
</xs:schema>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<BoneAttachment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BoneAttachment.xsd">
<Name></Name>
<PositionOffset X="0" Y="0" Z="0"/>
<OrientationOffset X="0" Y="0" Z="0"/>
<ScaleOffset X="1" Y="1" Z="1"/>
<InheritPosition>true</InheritPosition>
<InheritOrientation>true</InheritOrientation>
<InheritScale>false</InheritScale>
</BoneAttachment>
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="BoneAttachment">
<xs:complexType>
<xs:all>
<xs:element name="Name" type="t:string" minOccurs="0"/>
<xs:element name="PositionOffset" type="t:Vector" minOccurs="0"/>
<xs:element name="InheritPosition" type="t:bool" minOccurs="0"/>
<xs:element name="OrientationOffset" type="t:Vector" minOccurs="0"/>
<xs:element name="InheritOrientation" type="t:bool" minOccurs="0"/>
<xs:element name="ScaleOffset" type="t:Vector" minOccurs="0"/>
<xs:element name="InheritScale" type="t:bool" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="AnimationTests" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitPlane.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-1.79600012" Y="0.200000003" Z="-5.20000029"/>
<Scale X="10" Y="10" Z="10"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:DirectionalLight/>
<c:Model>
<Resource>Models/DirectionalLightWidget.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="2.42800021" Z="-2.80000019"/>
<Orientation X="5.51900005" Y="3.65100026" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Animation>
<Name>Run</Name>
<Time>0.45698878438365576</Time>
<Speed>0.5</Speed>
</c:Animation>
<c:Model>
<Resource>Models/AssaultAnimated.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0" Z="0.219988048"/>
<Orientation X="0" Y="1.95300007" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0.745098054" G="0.623529434" R="1"/>
<Radius>12</Radius>
<Falloff>0.29999995231628418</Falloff>
</c:PointLight>
<c:Transform>
<Position X="0" Y="2.30650759" Z="0.323329508"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="0.564705908" R="0.56078434"/>
<Radius>7</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="1.63035285" Z="-1.18989873"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Test">
<Components>
<c:BoneAttachment>
<ScaleOffset X="0.200000003" Y="0.200000003" Z="0.200000003"/>
<Name>L_Foot</Name>
<InheritScale>true</InheritScale>
</c:BoneAttachment>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="19.6078434" R="1"/>
</c:Model>
<c:Transform>
<Position X="-0.0864050835" Y="0.271049351" Z="0.442295641"/>
<Scale X="0.200000003" Y="0.199999988" Z="0.200000033"/>
<Orientation X="-1.9622153" Y="0.00355640799" Z="-3.12462544"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Test">
<Components>
<c:BoneAttachment>
<ScaleOffset X="0.200000003" Y="0.200000003" Z="0.200000003"/>
<Name>R_Foot</Name>
<InheritScale>true</InheritScale>
</c:BoneAttachment>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="1" R="19.6078434"/>
</c:Model>
<c:Transform>
<Position X="0.120880835" Y="0.045114398" Z="-0.153178662"/>
<Scale X="0.200000003" Y="0.200000077" Z="0.200000077"/>
<Orientation X="-0.176647186" Y="0.236876175" Z="-3.10332251"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+3 -5
View File
@@ -3,7 +3,7 @@
<Components>
<c:Transform>
<Position X="0" Y="-0.00432979874" Z="0"/>
<Position X="2.5629313" Y="-1.99438679" Z="0"/>
</c:Transform>
</Components>
@@ -18,16 +18,14 @@
<Axis X="1.50000012" Y="-2.20000005" Z="2.10000014"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="2.87819886" Z="0"/>
<Position X="0.00367118185" Y="0" Z="0.200000003"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Animation>
<Name>Crouch Walk</Name>
<Time>701.10570384634161</Time>
<Speed>32</Speed>
<Name>Walk</Name>
</c:Animation>
<c:Model>
<Resource>Models/AssaultAnimated.mesh</Resource>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="Test" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:BoneAttachment>
<ScaleOffset X="0.200000003" Y="0.200000003" Z="0.200000003"/>
<Name>L_Foot</Name>
<InheritScale>true</InheritScale>
</c:BoneAttachment>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="19.6078434" R="1"/>
</c:Model>
<c:Transform>
<Position X="-0.0863945931" Y="0.221357167" Z="-0.0781617165"/>
<Scale X="0.199999973" Y="0.199999973" Z="0.199999973"/>
<Orientation X="-2.80262542" Y="0.0150706368" Z="-3.13294244"/>
</c:Transform>
</Components>
<Children/>
</Entity>
-2
View File
@@ -41,7 +41,5 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
}
}
}
@@ -0,0 +1,71 @@
#include "Rendering/BoneAttachmentSystem.h"
void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt)
{
if(!entity.HasComponent("Transform")) {
return;
}
auto parent = entity.FirstParentWithComponent("Animation");
if (!parent.HasComponent("Model")) {
return;
}
Model* model;
try {
model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]);
} catch (const std::exception&) {
return;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["Name"]);
if (!animation) {
return;
}
int id = skeleton->GetBoneID(entity["BoneAttachment"]["Name"]);
if(id == -1) {
return;
}
int currentKeyframeIndex = skeleton->GetKeyframe(*animation, parent["Animation"]["Time"]);
const Skeleton::Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex];
const Skeleton::Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()];
float alpha = ((double)parent["Animation"]["Time"] - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], currentFrame, nextFrame, alpha, 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;
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"];
}
}
+8 -3
View File
@@ -94,11 +94,16 @@ void DrawFinalPass::Draw(RenderScene& scene)
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
}*/
//TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :)
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
if (modelJob->Animation != nullptr) {
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones( *modelJob->Animation, modelJob->AnimationTime);
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime);
// std::vector<glm::mat4> frameBones2 = modelJob->Skeleton->GetFrameBones(*modelJob->Skeleton->GetAnimation("Walk"), modelJob->AnimationTime);
//
//
// for (int i = 0; i < frameBones.size(); i++) {
// frameBones[i] = frameBones[i] * glm::mat4(glm::quat(glm::vec3(0.f, 0.f, 0.f)));//* frameBones2[i];
// }
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
}
+30
View File
@@ -66,6 +66,8 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation& animation, doubl
return finalMatrices;
}
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe &currentFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
{
glm::mat4 boneMatrix;
@@ -101,6 +103,34 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
}
glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix)
{
glm::mat4 boneMatrix;
if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) {
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties.at(bone->ID);
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;
boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * parentMatrix;
} else {
if (bone->Parent) {
boneMatrix = parentMatrix;
}
}
if(bone->Parent) {
return GetBoneTransform(bone->Parent, currentFrame, nextFrame, progress, boneMatrix);
} else {
return boneMatrix;
}
}
int Skeleton::GetBoneID(std::string name)
{
if (m_BonesByName.find(name) == m_BonesByName.end()) {
+3 -1
View File
@@ -10,7 +10,8 @@
#include "Core/EntityFileWriter.h"
#include "Game/Systems/CapturePointSystem.h"
#include "Game/Systems/WeaponSystem.h"
#include "../Engine/Rendering/AnimationSystem.h"
#include "Rendering/AnimationSystem.h"
#include "Rendering/BoneAttachmentSystem.h"
Game::Game(int argc, char* argv[])
{
@@ -90,6 +91,7 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
// Collision and TriggerSystem should update after player.
++updateOrderLevel;
m_SystemPipeline->AddSystem<BoneAttachmentSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeCollision);
++updateOrderLevel;