Removed AnimationOffset and improved BlendTree
This commit is contained in:
@@ -28,6 +28,7 @@ struct EntityWrapper
|
|||||||
void AttachComponent(const char* componentName);
|
void AttachComponent(const char* componentName);
|
||||||
EntityWrapper Parent();
|
EntityWrapper Parent();
|
||||||
EntityWrapper FirstChildByName(const std::string& name);
|
EntityWrapper FirstChildByName(const std::string& name);
|
||||||
|
EntityWrapper FirstLevelChildByName(const std::string& name);
|
||||||
EntityWrapper FirstParentWithComponent(const std::string& componentType);
|
EntityWrapper FirstParentWithComponent(const std::string& componentType);
|
||||||
bool IsChildOf(EntityWrapper potentialParent);
|
bool IsChildOf(EntityWrapper potentialParent);
|
||||||
bool Valid() const;
|
bool Valid() const;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
|
|
||||||
std::vector<glm::mat4> GetFinalPose() { return m_FinalPose; }
|
std::vector<glm::mat4> GetFinalPose() { return m_FinalPose; }
|
||||||
glm::mat4 GetBoneTransform(int boneID);
|
glm::mat4 GetBoneTransform(int boneID);
|
||||||
|
bool IsValid() { return (m_Root == nullptr ? false : true); }
|
||||||
|
|
||||||
void PrintTree();
|
void PrintTree();
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
<xs:include schemaLocation="Components/HiddenForLocalPlayer.xsd"/>
|
<xs:include schemaLocation="Components/HiddenForLocalPlayer.xsd"/>
|
||||||
<xs:include schemaLocation="Components/HealthPickup.xsd"/>
|
<xs:include schemaLocation="Components/HealthPickup.xsd"/>
|
||||||
<xs:include schemaLocation="Components/AmmoPickup.xsd"/>
|
<xs:include schemaLocation="Components/AmmoPickup.xsd"/>
|
||||||
<xs:include schemaLocation="Components/AnimationOffset.xsd"/>
|
|
||||||
<xs:include schemaLocation="Components/DashAbility.xsd"/>
|
<xs:include schemaLocation="Components/DashAbility.xsd"/>
|
||||||
<xs:include schemaLocation="Components/AssaultWeapon.xsd"/>
|
<xs:include schemaLocation="Components/AssaultWeapon.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Shield.xsd"/>
|
<xs:include schemaLocation="Components/Shield.xsd"/>
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
|
||||||
<AnimationOffset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AnimationOffset.xsd">
|
|
||||||
<AnimationName></AnimationName>
|
|
||||||
<Time>0</Time>
|
|
||||||
</AnimationOffset>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?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="AnimationOffset">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Aim animation offset for the skeleton</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:all>
|
|
||||||
<xs:element name="AnimationName" type="t:string" minOccurs="0"/>
|
|
||||||
<xs:element name="Time" type="t:double" minOccurs="0"/>
|
|
||||||
</xs:all>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:schema>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,6 @@
|
|||||||
<xs:element ref="c:AmmunitionHUD" minOccurs="0"/>
|
<xs:element ref="c:AmmunitionHUD" minOccurs="0"/>
|
||||||
<xs:element ref="c:KillFeed" minOccurs="0"/>
|
<xs:element ref="c:KillFeed" minOccurs="0"/>
|
||||||
<xs:element ref="c:Sprite" minOccurs="0"/>
|
<xs:element ref="c:Sprite" minOccurs="0"/>
|
||||||
<xs:element ref="c:AnimationOffset" minOccurs="0"/>
|
|
||||||
<xs:element ref="c:Menu" minOccurs="0"/>
|
<xs:element ref="c:Menu" minOccurs="0"/>
|
||||||
<xs:element ref="c:Page" minOccurs="0"/>
|
<xs:element ref="c:Page" minOccurs="0"/>
|
||||||
<xs:element ref="c:Button" minOccurs="0"/>
|
<xs:element ref="c:Button" minOccurs="0"/>
|
||||||
|
|||||||
@@ -39,6 +39,31 @@ EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
|
|||||||
return firstChildByNameRecursive(name, this->ID);
|
return firstChildByNameRecursive(name, this->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EntityWrapper EntityWrapper::FirstLevelChildByName(const std::string& name)
|
||||||
|
{
|
||||||
|
EntityID parent = this->ID;
|
||||||
|
if (!this->World->ValidEntity(parent)) {
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto itPair = this->World->GetChildren(parent);
|
||||||
|
if (itPair.first == itPair.second) {
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = itPair.first; it != itPair.second; ++it) {
|
||||||
|
std::string itName = this->World->GetName(it->second);
|
||||||
|
if (itName == name) {
|
||||||
|
return EntityWrapper(this->World, it->second);
|
||||||
|
} else if (it->second != EntityID_Invalid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType)
|
EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType)
|
||||||
{
|
{
|
||||||
EntityWrapper entity = *this;
|
EntityWrapper entity = *this;
|
||||||
|
|||||||
@@ -34,7 +34,16 @@ void AnimationSystem::CreateBlendTrees()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
skeleton->BlendTrees[entity] = std::shared_ptr<BlendTree>(new BlendTree(entity, skeleton));
|
if (entity.HasComponent("Blend") || entity.HasComponent("BlendOverride") ||
|
||||||
|
entity.HasComponent("BlendAdditive") || entity.HasComponent("Animation"))
|
||||||
|
{
|
||||||
|
std::shared_ptr<BlendTree> blendTree = std::shared_ptr<BlendTree>(new BlendTree(entity, skeleton));
|
||||||
|
|
||||||
|
if(blendTree->IsValid()) {
|
||||||
|
skeleton->BlendTrees[entity] = blendTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,11 +56,16 @@ void AnimationSystem::UpdateAnimations(double dt)
|
|||||||
|
|
||||||
for (auto& animationC : *animationComponents) {
|
for (auto& animationC : *animationComponents) {
|
||||||
EntityWrapper entity = EntityWrapper(m_World, animationC.EntityID);
|
EntityWrapper entity = EntityWrapper(m_World, animationC.EntityID);
|
||||||
EntityWrapper parent = entity.FirstParentWithComponent("Model");
|
EntityWrapper modelEntity;
|
||||||
|
if(!entity.HasComponent("Model")) {
|
||||||
|
modelEntity = entity.FirstParentWithComponent("Model");
|
||||||
|
} else {
|
||||||
|
modelEntity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
Model* model;
|
Model* model;
|
||||||
try {
|
try {
|
||||||
model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]);
|
model = ResourceManager::Load<::Model, true>(modelEntity["Model"]["Resource"]);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ BlendTree::BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton)
|
|||||||
m_Skeleton = skeleton;
|
m_Skeleton = skeleton;
|
||||||
|
|
||||||
|
|
||||||
auto itPair = ModelEntity.World->GetChildren(ModelEntity.ID);
|
|
||||||
if (itPair.first == itPair.second) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (ModelEntity.HasComponent("Animation")) {
|
if (ModelEntity.HasComponent("Animation")) {
|
||||||
const Skeleton::Animation* animation = skeleton->GetAnimation(ModelEntity["Animation"]["AnimationName"]);
|
const Skeleton::Animation* animation = skeleton->GetAnimation(ModelEntity["Animation"]["AnimationName"]);
|
||||||
@@ -59,20 +54,21 @@ BlendTree::BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton)
|
|||||||
BlendTree::~BlendTree()
|
BlendTree::~BlendTree()
|
||||||
{
|
{
|
||||||
Node* currentNode = m_Root;
|
Node* currentNode = m_Root;
|
||||||
|
if (currentNode != nullptr) {
|
||||||
|
while (currentNode->Child[0] != nullptr) {
|
||||||
|
currentNode = currentNode->Child[0];
|
||||||
|
}
|
||||||
|
|
||||||
while (currentNode->Child[0] != nullptr) {
|
std::list<Node*> m_NodesToRemove;
|
||||||
currentNode = currentNode->Child[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Node*> m_NodesToRemove;
|
while (currentNode != nullptr) {
|
||||||
|
m_NodesToRemove.push_back(currentNode);
|
||||||
|
currentNode = currentNode->Next();
|
||||||
|
}
|
||||||
|
|
||||||
while (currentNode != nullptr) {
|
for (auto it = m_NodesToRemove.begin(); it != m_NodesToRemove.end(); it++) {
|
||||||
m_NodesToRemove.push_back(currentNode);
|
delete (*it);
|
||||||
currentNode = currentNode->Next();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = m_NodesToRemove.begin(); it != m_NodesToRemove.end(); it++) {
|
|
||||||
delete (*it);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +103,7 @@ void BlendTree::PrintTree()
|
|||||||
|
|
||||||
BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity)
|
BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity)
|
||||||
{
|
{
|
||||||
EntityWrapper childEntity = parentEntity.FirstChildByName(name); // Make first level child by name
|
EntityWrapper childEntity = parentEntity.FirstLevelChildByName(name); // Make first level child by name
|
||||||
|
|
||||||
if (!childEntity.Valid()) {
|
if (!childEntity.Valid()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -133,8 +129,16 @@ BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, E
|
|||||||
node->Type = NodeType::Blend;
|
node->Type = NodeType::Blend;
|
||||||
(double&)childEntity["Blend"]["Weight"] = glm::clamp((float)(double)childEntity["Blend"]["Weight"], 0.f, 1.f);
|
(double&)childEntity["Blend"]["Weight"] = glm::clamp((float)(double)childEntity["Blend"]["Weight"], 0.f, 1.f);
|
||||||
node->Weight = (double)childEntity["Blend"]["Weight"];
|
node->Weight = (double)childEntity["Blend"]["Weight"];
|
||||||
node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity);
|
if (node->Weight < 1.f && node->Weight > 0.f) {
|
||||||
node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity);
|
node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity);
|
||||||
|
node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity);
|
||||||
|
} else if (node->Weight == 1.f) {
|
||||||
|
node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity);
|
||||||
|
} else if (node->Weight == 0.f) {
|
||||||
|
node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
} else if (childEntity.HasComponent("BlendOverride")) {
|
} else if (childEntity.HasComponent("BlendOverride")) {
|
||||||
Node* node = new Node();
|
Node* node = new Node();
|
||||||
@@ -213,7 +217,7 @@ void BlendTree::Blend(std::map<int, glm::mat4>& pose)
|
|||||||
std::vector<glm::mat4> BlendTree::AccumulateFinalPose()
|
std::vector<glm::mat4> BlendTree::AccumulateFinalPose()
|
||||||
{
|
{
|
||||||
std::vector<glm::mat4> finalPose;
|
std::vector<glm::mat4> finalPose;
|
||||||
if (m_Skeleton == nullptr || m_Root == nullptr) {
|
if (m_Skeleton == nullptr || m_Root == nullptr || (m_Root->Child[0] == nullptr && m_Root->Child[1] == nullptr)) {
|
||||||
|
|
||||||
for (int i = 0; i < m_Skeleton->Bones.size(); i++) {
|
for (int i = 0; i < m_Skeleton->Bones.size(); i++) {
|
||||||
finalPose.push_back(glm::mat4(1));
|
finalPose.push_back(glm::mat4(1));
|
||||||
|
|||||||
Reference in New Issue
Block a user