Added BlendTree that stores and blends multiple animations
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
#ifndef BlendTree_h__
|
||||
#define BlendTree_h__
|
||||
|
||||
#include "Common.h"
|
||||
#include "../GLM.h"
|
||||
#include "Skeleton.h"
|
||||
#include "../Core/EntityWrapper.h"
|
||||
#include "../Core/World.h"
|
||||
#include <stack>
|
||||
|
||||
class BlendTree
|
||||
{
|
||||
public:
|
||||
enum class NodeType
|
||||
{
|
||||
Additive,
|
||||
Blend,
|
||||
Override,
|
||||
Animation,
|
||||
};
|
||||
|
||||
|
||||
struct Node
|
||||
{
|
||||
std::string Name;
|
||||
Node* Parent = nullptr;
|
||||
Node* Child[2] = { nullptr, nullptr };
|
||||
NodeType Type;
|
||||
std::vector<glm::mat4> Pose;
|
||||
float Weight = 0.f;
|
||||
|
||||
Node* Next() {
|
||||
Node* next = this;
|
||||
|
||||
if (next->Child[1] == nullptr) {
|
||||
// Node has no right child
|
||||
next = this;
|
||||
while (next->Parent != nullptr && next == next->Parent->Child[1]) {
|
||||
next = next->Parent;
|
||||
}
|
||||
next = next->Parent;
|
||||
} else {
|
||||
// Find the leftmost node in the right subtree
|
||||
next = next->Child[1];
|
||||
while (next->Child[0] != nullptr) {
|
||||
next = next->Child[0];
|
||||
}
|
||||
}
|
||||
|
||||
return next;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton);
|
||||
~BlendTree();
|
||||
|
||||
std::vector<glm::mat4> GetBoneTransforms(Skeleton* skeleton);
|
||||
|
||||
void PrintTree();
|
||||
|
||||
private:
|
||||
Node* m_Root = nullptr;
|
||||
|
||||
void FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton* skeleton);
|
||||
BlendTree::Node* FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity, Skeleton* skeleton);
|
||||
|
||||
void Blend(Skeleton* skeleton, std::vector<glm::mat4>& pose);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../Core/Transform.h"
|
||||
#include "Skeleton.h"
|
||||
#include "ShaderProgram.h"
|
||||
#include "BlendTree.h"
|
||||
|
||||
struct ModelJob : RenderJob
|
||||
{
|
||||
@@ -122,41 +123,11 @@ struct ModelJob : RenderJob
|
||||
Skeleton = Model->m_RawModel->m_Skeleton;
|
||||
|
||||
if (Skeleton != nullptr) {
|
||||
if (world->HasComponent(Entity, "Animation")) {
|
||||
auto animationComponent = world->GetComponent(Entity, "Animation");
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
::Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)animationComponent["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)animationComponent["Weight" + std::to_string(i)];
|
||||
|
||||
if((int)animationComponent["BlendType" + std::to_string(i)].Enum("Additive") == (int)animationComponent["BlendType" + std::to_string(i)]) {
|
||||
animationData.blendType = Skeleton::BlendType::Additive;
|
||||
} else if ((int)animationComponent["BlendType" + std::to_string(i)].Enum("Blend") == (int)animationComponent["BlendType" + std::to_string(i)]) {
|
||||
animationData.blendType = Skeleton::BlendType::Blend;
|
||||
} else if ((int)animationComponent["BlendType" + std::to_string(i)].Enum("Override") == (int)animationComponent["BlendType" + std::to_string(i)]) {
|
||||
animationData.blendType = Skeleton::BlendType::Override;
|
||||
}
|
||||
|
||||
animationData.level = (int)animationComponent["Level" + std::to_string(i)];
|
||||
Animations.push_back(animationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (world->HasComponent(Entity, "AnimationOffset")) {
|
||||
auto animationOffsetComponent = world->GetComponent(Entity, "AnimationOffset");
|
||||
AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationOffsetComponent["AnimationName"]);
|
||||
AnimationOffset.time = (double)animationOffsetComponent["Time"];
|
||||
} else {
|
||||
AnimationOffset.animation = nullptr;
|
||||
}
|
||||
|
||||
EntityWrapper entityWrapper = EntityWrapper(world, modelComponent.EntityID);
|
||||
BlendTree = new ::BlendTree(entityWrapper, Skeleton);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
unsigned int TextureID;
|
||||
@@ -178,7 +149,7 @@ struct ModelJob : RenderJob
|
||||
std::vector<::Skeleton::AnimationData> Animations;
|
||||
::Skeleton::AnimationOffset AnimationOffset;
|
||||
|
||||
|
||||
::BlendTree* BlendTree = nullptr;
|
||||
|
||||
glm::vec4 DiffuseColor;
|
||||
glm::vec4 SpecularColor;
|
||||
|
||||
@@ -74,6 +74,7 @@ public:
|
||||
Blend,
|
||||
Override,
|
||||
};
|
||||
|
||||
struct AnimationData
|
||||
{
|
||||
const Animation* animation;
|
||||
@@ -108,26 +109,24 @@ public:
|
||||
|
||||
int GetBoneID(std::string name);
|
||||
|
||||
std::vector<glm::mat4> GetFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion = false);
|
||||
std::vector<glm::mat4> GetFrameBones(std::vector<AnimationData> animations, bool noRootMotion = false);
|
||||
std::vector<glm::mat4> GetFrameBones();
|
||||
|
||||
std::vector<glm::mat4> GetFrameBones(const Animation* animation, double time, bool additive, bool noRootMotion = false);
|
||||
void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix);
|
||||
|
||||
const Animation* GetAnimation(std::string name);
|
||||
|
||||
void AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& frameBones, const Bone* bone, glm::mat4 parentMatrix);
|
||||
void AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, std::map<int, glm::mat4>& frameBones, const Bone* bone, glm::mat4 parentMatrix);
|
||||
|
||||
glm::mat4 AdditiveBlend(const Bone* bone, AnimationOffset animationOffset, glm::mat4 targetPose);
|
||||
|
||||
void PrintSkeleton();
|
||||
void PrintSkeleton(const Bone* parent, int depthCount);
|
||||
std::map<std::string, Animation> Animations;
|
||||
|
||||
glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix);
|
||||
glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, AnimationOffset animationOffset, glm::mat4 childMatrix);
|
||||
glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix);
|
||||
int GetKeyframe(const Animation& animation, double time);
|
||||
|
||||
|
||||
std::vector<glm::mat4> BlendPoses(std::vector<glm::mat4> pose1, std::vector<glm::mat4> pose2, float weight);
|
||||
std::vector<glm::mat4> OverridePose(std::vector<glm::mat4> overridePose, std::vector<glm::mat4> targetPose);
|
||||
|
||||
private:
|
||||
glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset);
|
||||
glm::mat4 GetBonePose(const Bone* bone, const Animation* animation, double time, bool noRootMotion);
|
||||
|
||||
@@ -39,4 +39,7 @@
|
||||
<xs:include schemaLocation="Components/Sprite.xsd"/>
|
||||
<xs:include schemaLocation="Components/Shielded.xsd"/>
|
||||
<xs:include schemaLocation="Components/CapturePointHUD.xsd"/>
|
||||
<xs:include schemaLocation="Components/BlendOverride.xsd"/>
|
||||
<xs:include schemaLocation="Components/Blend.xsd"/>
|
||||
<xs:include schemaLocation="Components/BlendAdditive.xsd"/>
|
||||
</xs:schema>
|
||||
@@ -1,24 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
|
||||
<AnimationName1></AnimationName1>
|
||||
<BlendType1><Blend/></BlendType1>
|
||||
<Level1>0</Level1>
|
||||
<Weight1>1.0</Weight1>
|
||||
<Time1>0</Time1>
|
||||
<Speed1>0</Speed1>
|
||||
<Loop1>true</Loop1>
|
||||
<AnimationName2></AnimationName2>
|
||||
<BlendType2><Blend/></BlendType2>
|
||||
<Level2>0</Level2>
|
||||
<Weight2>1.0</Weight2>
|
||||
<Time2>0</Time2>
|
||||
<Speed2>0</Speed2>
|
||||
<Loop2>true</Loop2>
|
||||
<AnimationName3></AnimationName3>
|
||||
<BlendType3><Blend/></BlendType3>
|
||||
<Level3>0</Level3>
|
||||
<Weight3>1.0</Weight3>
|
||||
<Time3>0</Time3>
|
||||
<Speed3>0</Speed3>
|
||||
<Loop3>true</Loop3>
|
||||
<AnimationName></AnimationName>
|
||||
<Time>0</Time>
|
||||
<Speed>0</Speed>
|
||||
<Loop>true</Loop>
|
||||
<Additive>false</Additive>
|
||||
</Animation>
|
||||
@@ -2,48 +2,15 @@
|
||||
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||
|
||||
<xs:complexType name="BlendEnum" mixed="true">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="t:enum">
|
||||
<xs:choice>
|
||||
<xs:element name="Additive" type="xs:integer" fixed="0" minOccurs="0"/>
|
||||
<xs:element name="Blend" type="xs:integer" fixed="1" minOccurs="0"/>
|
||||
<xs:element name="Override" type="xs:integer" fixed="2" minOccurs="0"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
|
||||
<xs:element name="Animation">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="AnimationName1" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="BlendType1" type="BlendEnum" minOccurs="0"/>
|
||||
<xs:element name="Level1" type="t:int" minOccurs="0"/>
|
||||
<xs:element name="Weight1" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Time1" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Speed1" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Loop1" type="t:bool" minOccurs="0"/>
|
||||
|
||||
<xs:element name="AnimationName2" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="BlendType2" type="BlendEnum" minOccurs="0"/>
|
||||
<xs:element name="Level2" type="t:int" minOccurs="0"/>
|
||||
<xs:element name="Weight2" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Time2" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Speed2" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Loop2" type="t:bool" minOccurs="0"/>
|
||||
|
||||
<xs:element name="AnimationName3" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="BlendType3" type="BlendEnum" minOccurs="0"/>
|
||||
<xs:element name="Level3" type="t:int" minOccurs="0"/>
|
||||
<xs:element name="Weight3" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Time3" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Speed3" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Loop3" type="t:bool" minOccurs="0"/>
|
||||
<xs:element name="AnimationName" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Time" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Speed" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Loop" type="t:bool" minOccurs="0"/>
|
||||
<xs:element name="Additive" type="t:bool" minOccurs="0"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="replicated" type="xs:boolean" fixed="true"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Blend xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Blend.xsd">
|
||||
<Pose1></Pose1>
|
||||
<Pose2></Pose2>
|
||||
<Weight>0.5</Weight>
|
||||
</Blend>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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="Blend">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Pose1" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Pose2" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Weight" type="t:double" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<BlendAdditive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BlendAdditive.xsd">
|
||||
<Adder></Adder>
|
||||
<Receiver></Receiver>
|
||||
</BlendAdditive>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?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="BlendAdditive">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Adder" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Receiver" type="t:string" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<BlendOverride xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BlendOverride.xsd">
|
||||
<Master></Master>
|
||||
<Slave></Slave>
|
||||
<Weight>1.0</Weight>
|
||||
</BlendOverride>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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="BlendOverride">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Master" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Slave" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Weight" type="t:double" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -26,42 +26,6 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity name="Running">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>Run</AnimationName1>
|
||||
<Speed1>1</Speed1>
|
||||
<AnimationName2>StrafeRight</AnimationName2>
|
||||
<Weight1>0.5</Weight1>
|
||||
<Time1>0.98334510030765165</Time1>
|
||||
<Weight2>0.5</Weight2>
|
||||
<Time2>0.97153983043137671</Time2>
|
||||
<Speed2>1</Speed2>
|
||||
<Time3>0.093923612201312068</Time3>
|
||||
<Speed3>1</Speed3>
|
||||
</c:Animation>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="-1" Y="0" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:BoneAttachment>
|
||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||
</c:BoneAttachment>
|
||||
<c:Model>
|
||||
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:PointLight>
|
||||
@@ -99,35 +63,19 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Entity name="Assault">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>Run</AnimationName1>
|
||||
<Speed1>1</Speed1>
|
||||
<AnimationName2>StrafeRight</AnimationName2>
|
||||
<Weight1>0.5</Weight1>
|
||||
<Time1>0.98334510030765165</Time1>
|
||||
<Weight2>0.5</Weight2>
|
||||
<Time2>0.89665639003541542</Time2>
|
||||
<Speed2>1</Speed2>
|
||||
<AnimationName3>ShootFastRifle</AnimationName3>
|
||||
<BlendType3>
|
||||
<Override/>
|
||||
</BlendType3>
|
||||
<Time3>0.099759525382621339</Time3>
|
||||
<Speed3>1</Speed3>
|
||||
</c:Animation>
|
||||
<c:AnimationOffset>
|
||||
<AnimationName>AimRifle</AnimationName>
|
||||
<Time>0.68999981880187988</Time>
|
||||
</c:AnimationOffset>
|
||||
<c:Blend>
|
||||
<Pose1>BlendOverride</Pose1>
|
||||
<Pose2>AimAdditive</Pose2>
|
||||
</c:Blend>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Entity name="WeaponAttachment">
|
||||
<Components>
|
||||
<c:BoneAttachment>
|
||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||
@@ -136,45 +84,79 @@
|
||||
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0.146727413" Y="1.15066242" Z="-0.195905238"/>
|
||||
<Scale X="1.00000012" Y="1" Z="1.00000012"/>
|
||||
<Orientation X="0.38856402" Y="0.017387826" Z="0.0776973143"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>AimRifle</AnimationName1>
|
||||
<Speed1>0.5</Speed1>
|
||||
<AnimationName2>Ru</AnimationName2>
|
||||
<Time1>0.57926159055711501</Time1>
|
||||
</c:Animation>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
<Transparent>true</Transparent>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="1" Y="0" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Entity name="AimAdditive">
|
||||
<Components>
|
||||
<c:BoneAttachment>
|
||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||
</c:BoneAttachment>
|
||||
<c:Model>
|
||||
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||
<Transparent>true</Transparent>
|
||||
</c:Model>
|
||||
<c:Animation>
|
||||
<AnimationName>AimRifle</AnimationName>
|
||||
<Time>0.1120316470564493</Time>
|
||||
<Speed>0.5</Speed>
|
||||
<Additive>true</Additive>
|
||||
</c:Animation>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity name="BlendOverride">
|
||||
<Components>
|
||||
<c:BlendOverride>
|
||||
<Master>ShootRifleAnimation</Master>
|
||||
<Slave>BlendWalkRun</Slave>
|
||||
</c:BlendOverride>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity name="BlendWalkRun">
|
||||
<Components>
|
||||
<c:Blend>
|
||||
<Pose1>RunAnimtaion</Pose1>
|
||||
<Pose2>WalkAnimation</Pose2>
|
||||
<Weight>1</Weight>
|
||||
</c:Blend>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity name="RunAnimtaion">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>Run</AnimationName>
|
||||
<Time>0.22406329411289949</Time>
|
||||
<Speed>1</Speed>
|
||||
</c:Animation>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity name="WalkAnimation">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>Walk</AnimationName>
|
||||
<Time>0.22406329411289949</Time>
|
||||
<Speed>1</Speed>
|
||||
</c:Animation>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
<Entity name="ShootRifleAnimation">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>ShootFastRifle</AnimationName>
|
||||
<Time>0.024060340702750871</Time>
|
||||
<Speed>1</Speed>
|
||||
</c:Animation>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
<xs:element ref="c:Shield" minOccurs="0"/>
|
||||
<xs:element ref="c:Shielded" minOccurs="0"/>
|
||||
<xs:element ref="c:CapturePointHUD" minOccurs="0"/>
|
||||
<xs:element ref="c:BlendOverride" minOccurs="0"/>
|
||||
<xs:element ref="c:Blend" minOccurs="0"/>
|
||||
<xs:element ref="c:BlendAdditive" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
@@ -2,57 +2,56 @@
|
||||
|
||||
void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt)
|
||||
{
|
||||
if(!entity.HasComponent("Model")) {
|
||||
return;
|
||||
}
|
||||
|
||||
EntityWrapper parent = entity.FirstParentWithComponent("Model");
|
||||
|
||||
Model* model;
|
||||
try {
|
||||
model = ResourceManager::Load<::Model, true>(entity["Model"]["Resource"]);
|
||||
model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]);
|
||||
} catch (const std::exception&) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
|
||||
if(skeleton == nullptr) {
|
||||
if (skeleton == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]);
|
||||
for (int i = 1; i <= 1; i++) {
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]);
|
||||
|
||||
if (animation == nullptr) {
|
||||
continue;;
|
||||
}
|
||||
|
||||
double animationSpeed = (double)animationComponent["Speed" + std::to_string(i)];
|
||||
double animationSpeed = (double)animationComponent["Speed"];
|
||||
|
||||
if (animationSpeed != 0.0) {
|
||||
double nextTime = (double)animationComponent["Time" + std::to_string(i)] + animationSpeed * dt;
|
||||
double nextTime = (double)animationComponent["Time"] + animationSpeed * dt;
|
||||
|
||||
|
||||
if (!(bool)animationComponent["Loop" + std::to_string(i)]) {
|
||||
if (!(bool)animationComponent["Loop"]) {
|
||||
if (nextTime > animation->Duration) {
|
||||
nextTime = animation->Duration;
|
||||
Events::AnimationComplete e;
|
||||
e.Entity = entity;
|
||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||
e.Name = (std::string)animationComponent["AnimationName"];
|
||||
m_EventBroker->Publish(e);
|
||||
} else if (nextTime < 0) {
|
||||
Events::AnimationComplete e;
|
||||
e.Entity = entity;
|
||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||
e.Name = (std::string)animationComponent["AnimationName"];
|
||||
m_EventBroker->Publish(e);
|
||||
nextTime = 0;
|
||||
}
|
||||
|
||||
(double&)animationComponent["Speed" + std::to_string(i)] = 0.0;
|
||||
(double&)animationComponent["Speed"] = 0.0;
|
||||
|
||||
} else {
|
||||
if (nextTime > animation->Duration) {
|
||||
Events::AnimationComplete e;
|
||||
e.Entity = entity;
|
||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||
e.Name = (std::string)animationComponent["AnimationName"];
|
||||
m_EventBroker->Publish(e);
|
||||
|
||||
while(nextTime > animation->Duration) {
|
||||
@@ -61,7 +60,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
} else if (nextTime < 0) {
|
||||
Events::AnimationComplete e;
|
||||
e.Entity = entity;
|
||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||
e.Name = (std::string)animationComponent["AnimationName"];
|
||||
m_EventBroker->Publish(e);
|
||||
|
||||
while (nextTime < 0) {
|
||||
@@ -70,7 +69,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
}
|
||||
}
|
||||
|
||||
(double&)animationComponent["Time" + std::to_string(i)] = nextTime;
|
||||
(double&)animationComponent["Time"] = nextTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
#include "Rendering/BlendTree.h"
|
||||
|
||||
BlendTree::BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton)
|
||||
{
|
||||
auto itPair = ModelEntity.World->GetChildren(ModelEntity.ID);
|
||||
if (itPair.first == itPair.second) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ModelEntity.HasComponent("Animation")) {
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(ModelEntity["Animation"]["AnimationName"]);
|
||||
if (animation == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Root = new Node();
|
||||
m_Root->Name = ModelEntity.Name();
|
||||
m_Root->Pose = skeleton->GetFrameBones(animation, (double)ModelEntity["Animation"]["Time"], (bool)ModelEntity["Animation"]["Additive"]);
|
||||
m_Root->Parent = nullptr;
|
||||
m_Root->Type = NodeType::Animation;
|
||||
|
||||
} else if (ModelEntity.HasComponent("Blend")) {
|
||||
m_Root = new Node();
|
||||
m_Root->Name = ModelEntity.Name();
|
||||
m_Root->Parent = nullptr;
|
||||
m_Root->Type = NodeType::Blend;
|
||||
m_Root->Weight = (double)ModelEntity["Blend"]["Weight"];
|
||||
m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["Blend"]["Pose1"], ModelEntity, skeleton);
|
||||
m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["Blend"]["Pose2"], ModelEntity, skeleton);
|
||||
|
||||
} else if (ModelEntity.HasComponent("BlendOverride")) {
|
||||
m_Root = new Node();
|
||||
m_Root->Name = ModelEntity.Name();
|
||||
m_Root->Parent = nullptr;
|
||||
m_Root->Type = NodeType::Override;
|
||||
m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendOverride"]["Master"], ModelEntity, skeleton);
|
||||
m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendOverride"]["Slave"], ModelEntity, skeleton);
|
||||
|
||||
} else if (ModelEntity.HasComponent("BlendAdditive")) {
|
||||
m_Root = new Node();
|
||||
m_Root->Name = ModelEntity.Name();
|
||||
m_Root->Parent = nullptr;
|
||||
m_Root->Type = NodeType::Additive;
|
||||
m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendAdditive"]["Adder"], ModelEntity, skeleton);
|
||||
m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendAdditive"]["Receiver"], ModelEntity, skeleton);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// PrintTree();
|
||||
}
|
||||
|
||||
BlendTree::~BlendTree()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BlendTree::PrintTree()
|
||||
{
|
||||
Node* currentNode = m_Root;
|
||||
LOG_INFO("\n\n");
|
||||
|
||||
while(currentNode->Child[0] != nullptr) {
|
||||
currentNode = currentNode->Child[0];
|
||||
}
|
||||
|
||||
while (currentNode != nullptr)
|
||||
{
|
||||
LOG_INFO("%s", currentNode->Name.c_str());
|
||||
currentNode = currentNode->Next();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlendTree::FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton* skeleton)
|
||||
{
|
||||
auto itPair = parentEntity.World->GetChildren(parentEntity.ID);
|
||||
if (itPair.first == itPair.second) {
|
||||
return; // no children
|
||||
}
|
||||
|
||||
unsigned int childIndex = 0;
|
||||
for (auto it = itPair.first; it != itPair.second; ++it) {
|
||||
|
||||
EntityWrapper childEntity = EntityWrapper(parentEntity.World, it->second);
|
||||
|
||||
if(!childEntity.Valid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (childEntity.HasComponent("Animation")) {
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(childEntity["Animation"]["AnimationName"]);
|
||||
if(animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Pose = skeleton->GetFrameBones(animation, (double)childEntity["Animation"]["Time"], (bool)childEntity["Animation"]["Additive"]);
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Animation;
|
||||
parentNode->Child[childIndex] = node;
|
||||
childIndex++;
|
||||
FillTree(node, childEntity, skeleton);
|
||||
|
||||
} else if (childEntity.HasComponent("Blend")) {
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Blend;
|
||||
node->Weight = (double)childEntity["Blend"]["Weight"];
|
||||
parentNode->Child[childIndex] = node;
|
||||
childIndex++;
|
||||
FillTree(node, childEntity, skeleton);
|
||||
|
||||
} else if (childEntity.HasComponent("BlendOverride")) {
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Override;
|
||||
parentNode->Child[childIndex] = node;
|
||||
childIndex++;
|
||||
FillTree(node, childEntity, skeleton);
|
||||
|
||||
} else if (childEntity.HasComponent("BlendAdditive")) {
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Additive;
|
||||
parentNode->Child[childIndex] = node;
|
||||
childIndex++;
|
||||
FillTree(node, childEntity, skeleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity, Skeleton* skeleton)
|
||||
{
|
||||
EntityWrapper childEntity = parentEntity.FirstChildByName(name);
|
||||
|
||||
if (!childEntity.Valid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (childEntity.HasComponent("Animation")) {
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(childEntity["Animation"]["AnimationName"]);
|
||||
if (animation == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Pose = skeleton->GetFrameBones(animation, (double)childEntity["Animation"]["Time"], (bool)childEntity["Animation"]["Additive"]);
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Animation;
|
||||
return node;
|
||||
|
||||
} else if (childEntity.HasComponent("Blend")) {
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Blend;
|
||||
node->Weight = (double)childEntity["Blend"]["Weight"];
|
||||
node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity, skeleton);
|
||||
node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity, skeleton);
|
||||
return node;
|
||||
} else if (childEntity.HasComponent("BlendOverride")) {
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Override;
|
||||
node->Child[0] = FillTreeByName(node, (std::string)childEntity["BlendOverride"]["Master"], childEntity, skeleton);
|
||||
node->Child[1] = FillTreeByName(node, (std::string)childEntity["BlendOverride"]["Slave"], childEntity, skeleton);
|
||||
return node;
|
||||
} else if (childEntity.HasComponent("BlendAdditive")) {
|
||||
Node* node = new Node();
|
||||
node->Name = childEntity.Name();
|
||||
node->Parent = parentNode;
|
||||
node->Type = NodeType::Additive;
|
||||
node->Child[0] = FillTreeByName(node, (std::string)childEntity["BlendAdditive"]["Adder"], childEntity, skeleton);
|
||||
node->Child[1] = FillTreeByName(node, (std::string)childEntity["BlendAdditive"]["Receiver"], childEntity, skeleton);
|
||||
return node;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BlendTree::Blend(Skeleton* skeleton, std::vector<glm::mat4>& pose)
|
||||
{
|
||||
Node* currentNode;
|
||||
Node* start = m_Root;
|
||||
while (start->Child[0] != nullptr) {
|
||||
start = start->Child[0];
|
||||
}
|
||||
|
||||
currentNode = start;
|
||||
LOG_INFO("\n\n");
|
||||
while (m_Root->Pose.size() == 0) {
|
||||
if(currentNode->Pose.size() == 0) {
|
||||
if(currentNode->Child[0]->Pose.size() != 0 && currentNode->Child[1]->Pose.size() != 0) {
|
||||
|
||||
switch (currentNode->Type) {
|
||||
case BlendTree::NodeType::Additive:
|
||||
currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight);
|
||||
break;
|
||||
case BlendTree::NodeType::Blend:
|
||||
currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight);
|
||||
break;
|
||||
case BlendTree::NodeType::Override:
|
||||
currentNode->Pose = skeleton->OverridePose(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose);
|
||||
break;
|
||||
case BlendTree::NodeType::Animation:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
LOG_INFO("Blending %s and %s", currentNode->Child[0]->Name.c_str(), currentNode->Child[1]->Name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
currentNode = currentNode->Next();
|
||||
|
||||
if (currentNode == nullptr) {
|
||||
currentNode = start;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pose = m_Root->Pose;
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> BlendTree::GetBoneTransforms(Skeleton* skeleton)
|
||||
{
|
||||
if (skeleton == nullptr || m_Root == nullptr) {
|
||||
std::vector<glm::mat4> pose;
|
||||
for (auto& b : skeleton->Bones) {
|
||||
pose.push_back(glm::mat4(1));
|
||||
}
|
||||
return pose;
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> pose;
|
||||
Blend(skeleton, pose);
|
||||
|
||||
return pose;
|
||||
}
|
||||
|
||||
@@ -40,15 +40,10 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
glm::mat4 boneTransform;
|
||||
|
||||
if (parent.HasComponent("Animation")) {
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
::Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["Animation"]["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)parent["Animation"]["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)parent["Animation"]["Weight" + std::to_string(i)];
|
||||
|
||||
::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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,11 +338,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
/*if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
@@ -365,11 +366,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
/*if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -410,11 +412,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindModelTextures(forwardSkinnedHandle, modelJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
/* if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->BlendTree->GetBoneTransforms(modelJob->Skeleton);
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -438,11 +441,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindModelTextures(forwardSplatMapSkinnedHandle, modelJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
/* if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->BlendTree->GetBoneTransforms(modelJob->Skeleton);
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -486,11 +490,12 @@ 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) {
|
||||
/*if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_ShieldToStencilProgram->Bind();
|
||||
@@ -544,11 +549,12 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
/* if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
if (GLERROR("Animation")) {
|
||||
@@ -583,11 +589,12 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
BindModelTextures(forwardHandle ,modelJob);
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
/* if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
|
||||
@@ -619,11 +626,12 @@ 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) {
|
||||
/*if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -103,11 +103,12 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
/*if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
@@ -160,11 +161,12 @@ 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) {
|
||||
/* if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_PickingProgram->Bind();
|
||||
@@ -215,11 +217,12 @@ 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) {
|
||||
/* if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -276,11 +279,12 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
/*if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
}*/
|
||||
frameBones = modelJob->Skeleton->GetFrameBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
|
||||
@@ -41,29 +41,17 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones()
|
||||
{
|
||||
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);
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation* animation, const double time, bool additive, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
if (animation == nullptr) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));
|
||||
@@ -71,9 +59,9 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animat
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1));
|
||||
AccumulateBoneTransforms(true, animation, time, frameBones, additive, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
@@ -82,175 +70,74 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animat
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
std::vector<JointFramePose> JointPoses;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFramePose jointPose;
|
||||
jointPose.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) {
|
||||
nextFrame = currentFrame;
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
glm::quat rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
glm::vec3 scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
position.x = 0;
|
||||
position.z = 0;
|
||||
}
|
||||
|
||||
jointPose.Pose = (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
||||
JointPoses.push_back(jointPose);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointPose.Pose = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||
JointPoses.push_back(jointPose);
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
if (additive) {
|
||||
time += 1.0/60.0; // first frame is a reference frame
|
||||
}
|
||||
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
if (JointPoses.size() == 0) {
|
||||
if (bone->Parent) {
|
||||
|
||||
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
boneMatrix = parentMatrix * jointPose;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
}
|
||||
} else {
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
float totalWeight = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
for (JointFramePose jointFramePose : JointPoses) {
|
||||
totalWeight += jointFramePose.Weight;
|
||||
}
|
||||
float progress;
|
||||
|
||||
glm::mat4 finalBlend = glm::mat4(0);
|
||||
|
||||
for (JointFramePose jointFramePose : JointPoses) {
|
||||
if (jointFramePose.Weight == 1.0f) {
|
||||
finalBlend = jointFramePose.Pose;
|
||||
if (nextFrame.Index == 0) {
|
||||
nextFrame = currentFrame;
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
finalBlend += jointFramePose.Pose * (jointFramePose.Weight / totalWeight);
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
glm::quat rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
glm::vec3 scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
position.x = 0;
|
||||
position.z = 0;
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix * (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
boneMatrix = parentMatrix * finalBlend;
|
||||
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<JointFramePose> JointPoses;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
if (animationData.animation->JointAnimations.find(bone->ID) != animationData.animation->JointAnimations.end()) { // Does the bone have any keyframes in this animation?
|
||||
JointFramePose jointPose;
|
||||
jointPose.Weight = animationData.weight;
|
||||
jointPose.Type = animationData.blendType;
|
||||
jointPose.Level = animationData.level;
|
||||
jointPose.Pose = GetBonePose(bone, animationData.animation, animationData.time, noRootMotion);
|
||||
JointPoses.push_back(jointPose);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (JointPoses.size() == 0) { // No keyframes for the current bone
|
||||
} else { // 0 keyframes for the current bone
|
||||
if (bone->Parent) {
|
||||
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
||||
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, jointPose);
|
||||
boneMatrix = parentMatrix * boneTransform;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
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 {
|
||||
|
||||
|
||||
glm::mat4 finalBlend = glm::mat4(0);
|
||||
glm::mat4 finalOverride = glm::mat4(0);
|
||||
|
||||
int maxLevel = 0;
|
||||
for (JointFramePose jointPose : JointPoses) {
|
||||
maxLevel = jointPose.Level > maxLevel ? jointPose.Level : maxLevel;
|
||||
}
|
||||
|
||||
|
||||
for (JointFramePose jointPose : JointPoses) {
|
||||
if (jointPose.Type == BlendType::Override) {
|
||||
finalOverride += jointPose.Pose * jointPose.Weight; //Blend Overrides then apply to final blend
|
||||
} else if(jointPose.Type == BlendType::Blend) {
|
||||
finalBlend += jointPose.Pose * jointPose.Weight;
|
||||
} else if (jointPose.Type == BlendType::Additive) {
|
||||
//Soon
|
||||
}
|
||||
}
|
||||
|
||||
if(finalOverride != glm::mat4(0)) {
|
||||
finalBlend = finalOverride;
|
||||
}
|
||||
|
||||
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, finalBlend);
|
||||
boneMatrix = parentMatrix * boneTransform;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix);
|
||||
AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, additive, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +331,6 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, AnimationOffset animationOffset, glm::mat4 childMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
@@ -555,7 +441,6 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
@@ -673,6 +558,50 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
||||
return boneMatrix;
|
||||
}
|
||||
|
||||
|
||||
std::vector<glm::mat4> Skeleton::BlendPoses(std::vector<glm::mat4> pose1, std::vector<glm::mat4> pose2, float weight)
|
||||
{
|
||||
std::vector<glm::mat4> finalPose;
|
||||
|
||||
if(pose1.size() != pose2.size()) {
|
||||
LOG_ERROR("Number of bones does not match");
|
||||
return finalPose;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pose1.size(); i++) {
|
||||
glm::mat4 blendedPose = glm::mat4(0);
|
||||
|
||||
blendedPose += pose1[i] * weight;
|
||||
|
||||
blendedPose += pose2[i] * (1.f - weight);
|
||||
|
||||
finalPose.push_back(blendedPose);
|
||||
}
|
||||
|
||||
return finalPose;
|
||||
}
|
||||
|
||||
|
||||
std::vector<glm::mat4> Skeleton::OverridePose(std::vector<glm::mat4> overridePose, std::vector<glm::mat4> targetPose)
|
||||
{
|
||||
std::vector<glm::mat4> finalPose;
|
||||
|
||||
if (overridePose.size() != targetPose.size()) {
|
||||
LOG_ERROR("Number of bones does not match");
|
||||
return finalPose;
|
||||
}
|
||||
|
||||
for (int i = 0; i < overridePose.size(); i++) {
|
||||
if(overridePose[i] != glm::mat4(1)) {
|
||||
finalPose.push_back(overridePose[i]);
|
||||
} else {
|
||||
finalPose.push_back(targetPose[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return finalPose;
|
||||
}
|
||||
|
||||
int Skeleton::GetBoneID(std::string name)
|
||||
{
|
||||
if (m_BonesByName.find(name) == m_BonesByName.end()) {
|
||||
@@ -681,47 +610,3 @@ int Skeleton::GetBoneID(std::string name)
|
||||
return m_BonesByName.at(name)->ID;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::PrintSkeleton()
|
||||
{
|
||||
if (LOG_LEVEL < LOG_LEVEL_DEBUG) {
|
||||
return;
|
||||
}
|
||||
PrintSkeleton(RootBone, 0);
|
||||
}
|
||||
|
||||
void Skeleton::PrintSkeleton(const Bone* bone, int depthCount)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::string(depthCount, ' ');
|
||||
ss << bone->ID << ": " << bone->Name;
|
||||
std::cout << ss.str() << std::endl;
|
||||
|
||||
depthCount++;
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
PrintSkeleton(child, depthCount);
|
||||
}
|
||||
}
|
||||
|
||||
int Skeleton::GetKeyframe(const Animation& animation, double time)
|
||||
{
|
||||
|
||||
/*
|
||||
if (time < 0) {
|
||||
time = 0;
|
||||
}
|
||||
if (time >= animation.Duration) {
|
||||
return animation..size() - 1;
|
||||
}
|
||||
|
||||
for (int keyframe = 0; keyframe < animation.Keyframes.size(); ++keyframe) {
|
||||
if (animation.Keyframes[keyframe].Time > time) {
|
||||
return (keyframe - 1) % animation.Keyframes.size();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user