git mv Code\Sandbox\Editor Code/Editor
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "AnimationBipedBoneNames.h"
|
||||
|
||||
namespace EditorAnimationBones
|
||||
{
|
||||
namespace Biped
|
||||
{
|
||||
const char* Pelvis = "Bip01 Pelvis";
|
||||
const char* Head = "Bip01 Head";
|
||||
const char* Weapon = "weapon_bone";
|
||||
|
||||
const char* LeftEye = "eye_bone_left";
|
||||
const char* RightEye = "eye_bone_right";
|
||||
|
||||
const char* Spine[5] = { "Bip01 Spine", "Bip01 Spine1", "Bip01 Spine2", "Bip01 Spine3", "Bip01 Spine4" };
|
||||
const char* Neck[2] = { "Bip01 Neck", "Bip01 Neck1" };
|
||||
|
||||
const char* LeftHeel = "Bip01 L Heel";
|
||||
const char* LeftToe[2] = { "Bip01 L Toe0", "Bip01 L Toe1" };
|
||||
|
||||
const char* RightHeel = "Bip01 R Heel";
|
||||
const char* RightToe[2] = { "Bip01 R Toe0", "Bip01 R Toe1" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_ANIMATIONBIPEDBONENAMES_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_ANIMATIONBIPEDBONENAMES_H
|
||||
#pragma once
|
||||
|
||||
namespace EditorAnimationBones
|
||||
{
|
||||
namespace Biped
|
||||
{
|
||||
extern const char* Pelvis;
|
||||
extern const char* Head;
|
||||
extern const char* Weapon;
|
||||
|
||||
extern const char* Spine[5];
|
||||
extern const char* Neck[2];
|
||||
|
||||
extern const char* LeftEye;
|
||||
extern const char* RightEye;
|
||||
|
||||
extern const char* LeftHeel;
|
||||
extern const char* RightHeel;
|
||||
extern const char* LeftToe[2];
|
||||
extern const char* RightToe[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_ANIMATIONBIPEDBONENAMES_H
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
#include "SkeletonHierarchy.h"
|
||||
|
||||
using namespace Skeleton;
|
||||
|
||||
/*
|
||||
|
||||
CHierarchy
|
||||
|
||||
*/
|
||||
|
||||
CHierarchy::CHierarchy()
|
||||
{
|
||||
}
|
||||
|
||||
CHierarchy::~CHierarchy()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint32 CHierarchy::AddNode(const char* name, const QuatT& pose, int32 parent)
|
||||
{
|
||||
int32 index = FindNodeIndexByName(name);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
m_nodes.push_back(SNode());
|
||||
index = int32(m_nodes.size() - 1);
|
||||
}
|
||||
|
||||
m_nodes[index].name = name;
|
||||
m_nodes[index].pose = pose;
|
||||
m_nodes[index].parent = parent;
|
||||
return uint32(index);
|
||||
}
|
||||
|
||||
int32 CHierarchy::FindNodeIndexByName(const char* name) const
|
||||
{
|
||||
uint32 count = uint32(m_nodes.size());
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
if (::_stricmp(m_nodes[i].name, name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const CHierarchy::SNode* CHierarchy::FindNode(const char* name) const
|
||||
{
|
||||
int32 index = FindNodeIndexByName(name);
|
||||
return index < 0 ? NULL : &m_nodes[index];
|
||||
}
|
||||
|
||||
void CHierarchy::CreateFrom(IDefaultSkeleton* pIDefaultSkeleton)
|
||||
{
|
||||
const uint32 jointCount = pIDefaultSkeleton->GetJointCount();
|
||||
|
||||
m_nodes.clear();
|
||||
m_nodes.reserve(jointCount);
|
||||
for (uint32 i = 0; i < jointCount; ++i)
|
||||
{
|
||||
m_nodes.push_back(SNode());
|
||||
|
||||
m_nodes.back().name = pIDefaultSkeleton->GetJointNameByID(int32(i));
|
||||
m_nodes.back().pose = pIDefaultSkeleton->GetDefaultAbsJointByID(int32(i));
|
||||
|
||||
m_nodes.back().parent = pIDefaultSkeleton->GetJointParentIDByID(int32(i));
|
||||
}
|
||||
|
||||
ValidateReferences();
|
||||
}
|
||||
|
||||
void CHierarchy::ValidateReferences()
|
||||
{
|
||||
uint32 nodeCount = m_nodes.size();
|
||||
if (!nodeCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (m_nodes[i].parent < nodeCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_nodes[i].parent = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CHierarchy::AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination)
|
||||
{
|
||||
uint32 count = uint32(m_nodes.size());
|
||||
std::vector<QuatT> absolutes(count);
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
absolutes[i] = pSource[i];
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
int32 parent = m_nodes[i].parent;
|
||||
if (parent < 0)
|
||||
{
|
||||
pDestination[i] = absolutes[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
pDestination[i].t = (absolutes[i].t - absolutes[parent].t) * absolutes[parent].q;
|
||||
pDestination[i].q = absolutes[parent].q.GetInverted() * absolutes[i].q;
|
||||
}
|
||||
}
|
||||
|
||||
bool CHierarchy::SerializeTo(XmlNodeRef& node)
|
||||
{
|
||||
XmlNodeRef hierarchy = node->newChild("Hierarchy");
|
||||
|
||||
uint32 nodeCount = uint32(m_nodes.size());
|
||||
std::vector<IXmlNode*> nodes(nodeCount);
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
XmlNodeRef parent = hierarchy;
|
||||
if (m_nodes[i].parent > -1)
|
||||
{
|
||||
parent = nodes[m_nodes[i].parent];
|
||||
}
|
||||
|
||||
nodes[i] = parent->newChild("Node");
|
||||
nodes[i]->setAttr("name", m_nodes[i].name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
|
||||
#pragma once
|
||||
|
||||
namespace Skeleton {
|
||||
class CHierarchy
|
||||
: public _reference_target_t
|
||||
{
|
||||
public:
|
||||
struct SNode
|
||||
{
|
||||
string name;
|
||||
QuatT pose;
|
||||
|
||||
int32 parent;
|
||||
|
||||
/* TODO: Implement
|
||||
uint32 childrenIndex;
|
||||
uint32 childrenCount;
|
||||
*/
|
||||
};
|
||||
|
||||
public:
|
||||
CHierarchy();
|
||||
~CHierarchy();
|
||||
|
||||
public:
|
||||
uint32 AddNode(const char* name, const QuatT& pose, int32 parent = -1);
|
||||
uint32 GetNodeCount() const { return uint32(m_nodes.size()); }
|
||||
SNode* GetNode(uint32 index) { return &m_nodes[index]; }
|
||||
const SNode* GetNode(uint32 index) const { return &m_nodes[index]; }
|
||||
int32 FindNodeIndexByName(const char* name) const;
|
||||
const SNode* FindNode(const char* name) const;
|
||||
void ClearNodes() { m_nodes.clear(); }
|
||||
|
||||
void CreateFrom(IDefaultSkeleton* rIDefaultSkeleton);
|
||||
void ValidateReferences();
|
||||
|
||||
void AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination);
|
||||
|
||||
bool SerializeTo(XmlNodeRef& node);
|
||||
|
||||
private:
|
||||
std::vector<SNode> m_nodes;
|
||||
};
|
||||
} // namespace Skeleton
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
|
||||
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SkeletonMapper.h"
|
||||
|
||||
using namespace Skeleton;
|
||||
|
||||
/*
|
||||
|
||||
CMapper
|
||||
|
||||
*/
|
||||
|
||||
CMapper::CMapper()
|
||||
{
|
||||
}
|
||||
|
||||
CMapper::~CMapper()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void CMapper::CreateFromHierarchy()
|
||||
{
|
||||
m_nodes.clear();
|
||||
|
||||
uint32 nodeCount = m_hierarchy.GetNodeCount();
|
||||
m_nodes.resize(nodeCount);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint32 CMapper::CreateLocation(const char* name)
|
||||
{
|
||||
int32 index = FindLocation(name);
|
||||
if (index < 1)
|
||||
{
|
||||
CMapperLocation* pLocation = new CMapperLocation();
|
||||
pLocation->SetName(name);
|
||||
m_locations.push_back(pLocation);
|
||||
}
|
||||
return uint32(m_locations.size() - 1);
|
||||
}
|
||||
|
||||
void CMapper::ClearLocations()
|
||||
{
|
||||
uint32 count = uint32(m_nodes.size());
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
m_nodes[i].position = NULL;
|
||||
m_nodes[i].orientation = NULL;
|
||||
}
|
||||
|
||||
m_locations.clear();
|
||||
}
|
||||
|
||||
int32 CMapper::FindLocation(const char* name) const
|
||||
{
|
||||
uint32 count = uint32(m_locations.size());
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
if (::_stricmp(m_locations[i]->GetName(), name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return int32(i);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CMapper::SetLocation(CMapperLocation& location)
|
||||
{
|
||||
int32 index = FindLocation(location.GetName());
|
||||
if (index < 0)
|
||||
{
|
||||
m_locations.push_back(&location);
|
||||
return;
|
||||
}
|
||||
|
||||
m_locations[index] = &location;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapper::CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent)
|
||||
{
|
||||
if (NodeHasLocation(index))
|
||||
{
|
||||
const CHierarchy::SNode* pNode = m_hierarchy.GetNode(index);
|
||||
uint32 nodeIndex = hierarchy.AddNode(pNode->name, pNode->pose, hierarchyParent);
|
||||
hierarchyParent = uint32(nodeIndex);
|
||||
}
|
||||
|
||||
std::vector<uint32> children;
|
||||
GetChildrenIndices(index, children);
|
||||
uint32 childCount = uint32(children.size());
|
||||
for (uint32 i = 0; i < childCount; ++i)
|
||||
{
|
||||
CreateLocationsHierarchy(children[i], hierarchy, hierarchyParent);
|
||||
}
|
||||
|
||||
return hierarchy.GetNodeCount() != 0;
|
||||
}
|
||||
|
||||
bool CMapper::CreateLocationsHierarchy(CHierarchy& hierarchy)
|
||||
{
|
||||
hierarchy.ClearNodes();
|
||||
if (!CreateLocationsHierarchy(0, hierarchy, -1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hierarchy.ValidateReferences();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapper::Map(QuatT* pResult)
|
||||
{
|
||||
uint32 outputCount = m_hierarchy.GetNodeCount();
|
||||
std::vector<Quat> absolutes(outputCount);
|
||||
for (uint32 i = 0; i < outputCount; ++i)
|
||||
{
|
||||
pResult[i].SetIdentity();
|
||||
absolutes[i].SetIdentity();
|
||||
|
||||
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
|
||||
if (!pNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CHierarchy::SNode* pParent = pNode->parent < 0 ?
|
||||
NULL : m_hierarchy.GetNode(pNode->parent);
|
||||
if (pParent)
|
||||
{
|
||||
pResult[i].t =
|
||||
(pNode->pose.t - pParent->pose.t) * pParent->pose.q;
|
||||
}
|
||||
|
||||
if (m_nodes[i].position)
|
||||
{
|
||||
pResult[i].t = m_nodes[i].position->Compute().t;
|
||||
}
|
||||
|
||||
if (m_nodes[i].orientation)
|
||||
{
|
||||
absolutes[i] = m_nodes[i].orientation->Compute().q;
|
||||
}
|
||||
else if (pParent)
|
||||
{
|
||||
Quat relative = pParent->pose.q.GetInverted() * pNode->pose.q;
|
||||
absolutes[i] = absolutes[pNode->parent] * relative;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < outputCount; ++i)
|
||||
{
|
||||
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
|
||||
if (!pNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CHierarchy::SNode* pParent = pNode->parent < 0 ?
|
||||
NULL : m_hierarchy.GetNode(pNode->parent);
|
||||
if (!pParent)
|
||||
{
|
||||
pResult[i].q = absolutes[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
pResult[i].q = absolutes[i];
|
||||
if (!m_nodes[i].position)
|
||||
{
|
||||
pResult[i].t = pResult[pNode->parent].t +
|
||||
pResult[i].t * absolutes[pNode->parent].GetInverted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapper::NodeHasLocation(uint32 index)
|
||||
{
|
||||
if (CMapperOperator* pOperator = m_nodes[index].position)
|
||||
{
|
||||
if (pOperator->IsOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (pOperator->HasLinksOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (CMapperOperator* pOperator = m_nodes[index].orientation)
|
||||
{
|
||||
if (pOperator->IsOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (pOperator->HasLinksOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMapper::GetChildrenIndices(uint32 parent, std::vector<uint32>& children)
|
||||
{
|
||||
uint32 nodeCount = m_hierarchy.GetNodeCount();
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (m_hierarchy.GetNode(i)->parent != parent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
children.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapper::ChildrenHaveLocation(uint32 index)
|
||||
{
|
||||
std::vector<uint32> children;
|
||||
GetChildrenIndices(index, children);
|
||||
|
||||
uint32 childrenCount = uint32(children.size());
|
||||
for (uint32 i = 0; i < childrenCount; ++i)
|
||||
{
|
||||
if (ChildrenHaveLocation(children[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMapper::NodeOrChildrenHaveLocation(uint32 index)
|
||||
{
|
||||
if (NodeHasLocation(index))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint32> children;
|
||||
GetChildrenIndices(index, children);
|
||||
|
||||
uint32 childrenCount = uint32(children.size());
|
||||
for (uint32 i = 0; i < childrenCount; ++i)
|
||||
{
|
||||
if (NodeOrChildrenHaveLocation(children[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMapper::SerializeTo(XmlNodeRef& node)
|
||||
{
|
||||
XmlNodeRef hierarchy = node->newChild("Hierarchy");
|
||||
|
||||
uint32 nodeCount = GetNodeCount();
|
||||
std::vector<IXmlNode*> nodes(nodeCount);
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (!NodeOrChildrenHaveLocation(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
|
||||
if (!pNode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlNodeRef xmlParent = hierarchy;
|
||||
int32 parent = pNode->parent;
|
||||
if (parent > -1)
|
||||
{
|
||||
xmlParent = nodes[parent];
|
||||
}
|
||||
|
||||
nodes[i] = xmlParent->newChild("Node");
|
||||
nodes[i]->setAttr("name", pNode->name);
|
||||
|
||||
if (CMapperOperator* pOperator = m_nodes[i].position)
|
||||
{
|
||||
XmlNodeRef position = nodes[i]->newChild("Position");
|
||||
XmlNodeRef child = position->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (CMapperOperator* pOperator = m_nodes[i].orientation)
|
||||
{
|
||||
XmlNodeRef orientation = nodes[i]->newChild("Orientation");
|
||||
XmlNodeRef child = orientation->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapper::SerializeFrom(XmlNodeRef& node, int32 parent)
|
||||
{
|
||||
int childCount = uint32(node->getChildCount());
|
||||
for (int i = 0; i < childCount; ++i)
|
||||
{
|
||||
XmlNodeRef child = node->getChild(i);
|
||||
if (::_stricmp(child->getTag(), "Node"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 index = m_hierarchy.AddNode(child->getAttr("name"), QuatT(IDENTITY), parent);
|
||||
if (!SerializeFrom(child, int32(index)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapper::SerializeFrom(XmlNodeRef& node)
|
||||
{
|
||||
XmlNodeRef hierarchy = node->findChild("Hierarchy");
|
||||
if (!hierarchy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hierarchy.ClearNodes();
|
||||
|
||||
if (!SerializeFrom(hierarchy, -1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nodes.resize(m_hierarchy.GetNodeCount());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "SkeletonHierarchy.h"
|
||||
#include "SkeletonMapperOperator.h"
|
||||
|
||||
namespace Skeleton {
|
||||
class CMapper
|
||||
{
|
||||
public:
|
||||
struct SNode
|
||||
{
|
||||
_smart_ptr<CMapperOperator> position;
|
||||
_smart_ptr<CMapperOperator> orientation;
|
||||
};
|
||||
|
||||
public:
|
||||
CMapper();
|
||||
~CMapper();
|
||||
|
||||
public:
|
||||
CHierarchy& GetHierarchy() { return m_hierarchy; }
|
||||
void CreateFromHierarchy();
|
||||
|
||||
uint32 GetNodeCount() const { return uint32(m_nodes.size()); }
|
||||
SNode* GetNode(uint32 index) { return &m_nodes[index]; }
|
||||
const SNode* GetNode(uint32 index) const { return &m_nodes[index]; }
|
||||
|
||||
uint32 CreateLocation(const char* name);
|
||||
void ClearLocations();
|
||||
int32 FindLocation(const char* name) const;
|
||||
|
||||
uint32 GetLocationCount() const { return uint32(m_locations.size()); }
|
||||
void SetLocation(CMapperLocation& location);
|
||||
CMapperLocation* GetLocation(uint32 index) { return m_locations[index]; }
|
||||
const CMapperLocation* GetLocation(uint32 index) const { return m_locations[index]; }
|
||||
|
||||
bool CreateLocationsHierarchy(CHierarchy& hierarchy);
|
||||
|
||||
void Map(QuatT* pResult);
|
||||
|
||||
bool SerializeTo(XmlNodeRef& node);
|
||||
bool SerializeFrom(XmlNodeRef& node);
|
||||
|
||||
private:
|
||||
bool NodeHasLocation(uint32 index);
|
||||
bool ChildrenHaveLocation(uint32 index);
|
||||
bool NodeOrChildrenHaveLocation(uint32 index);
|
||||
|
||||
bool SerializeFrom(XmlNodeRef& node, int32 parent);
|
||||
|
||||
bool CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent = -1);
|
||||
|
||||
// TEMP
|
||||
void GetChildrenIndices(uint32 parent, std::vector<uint32>& children);
|
||||
|
||||
private:
|
||||
CHierarchy m_hierarchy;
|
||||
std::vector<_smart_ptr<CMapperLocation> > m_locations;
|
||||
|
||||
std::vector<SNode> m_nodes;
|
||||
};
|
||||
} // namespace Skeleton
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SkeletonMapperOperator.h"
|
||||
|
||||
using namespace Skeleton;
|
||||
|
||||
/*
|
||||
|
||||
CMapperOperatorDesc
|
||||
|
||||
*/
|
||||
|
||||
std::vector<CMapperOperatorDesc*> CMapperOperatorDesc::s_descs;
|
||||
|
||||
//
|
||||
|
||||
CMapperOperatorDesc::CMapperOperatorDesc(const char* name)
|
||||
{
|
||||
s_descs.push_back(this);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
CMapperOperator
|
||||
|
||||
*/
|
||||
|
||||
CMapperOperator::CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount)
|
||||
{
|
||||
m_className = className;
|
||||
m_position.resize(positionCount, NULL);
|
||||
m_orientation.resize(orientationCount, NULL);
|
||||
}
|
||||
|
||||
CMapperOperator::~CMapperOperator()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapperOperator::IsOfClass(const char* className)
|
||||
{
|
||||
if (::_stricmp(m_className, className))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 CMapperOperator::HasLinksOfClass(const char* className)
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
uint32 positionCount = m_position.size();
|
||||
for (uint32 i = 0; i < positionCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_position[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pOperator->IsOfClass(className))
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 orientationCount = m_orientation.size();
|
||||
for (uint32 i = 0; i < orientationCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_orientation[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pOperator->IsOfClass(className))
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapperOperator::SerializeTo(XmlNodeRef& node)
|
||||
{
|
||||
node->setAttr("class", m_className);
|
||||
|
||||
uint32 parameterCount = uint32(m_parameters.size());
|
||||
for (uint32 i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
m_parameters[i]->Serialize(node, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapperOperator::SerializeFrom(XmlNodeRef& node)
|
||||
{
|
||||
uint32 parameterCount = uint32(m_parameters.size());
|
||||
for (uint32 i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
m_parameters[i]->Serialize(node, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapperOperator::SerializeWithLinksTo(XmlNodeRef& node)
|
||||
{
|
||||
if (!SerializeTo(node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 positionCount = uint32(m_position.size());
|
||||
for (uint32 i = 0; i < positionCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_position[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlNodeRef position = node->newChild("Position");
|
||||
position->setAttr("index", i);
|
||||
|
||||
XmlNodeRef child = position->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 orientationCount = uint32(m_orientation.size());
|
||||
for (uint32 i = 0; i < orientationCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_orientation[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlNodeRef orientation = node->newChild("Orientation");
|
||||
orientation->setAttr("index", i);
|
||||
|
||||
XmlNodeRef child = orientation->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapperOperator::SerializeWithLinksFrom(XmlNodeRef& node)
|
||||
{
|
||||
if (!SerializeFrom(node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
|
||||
CMapperOperator_Transform
|
||||
|
||||
*/
|
||||
|
||||
class CMapperOperator_Transform
|
||||
: public CMapperOperator
|
||||
{
|
||||
public:
|
||||
CMapperOperator_Transform()
|
||||
: CMapperOperator("Transform", 1, 1)
|
||||
{
|
||||
m_pAngles = new CVariable<Vec3>();
|
||||
m_pAngles->SetName("rotation");
|
||||
m_pAngles->Set(Vec3(0.0f, 0.0f, 0.0f));
|
||||
m_pAngles->SetLimits(-180.0f, 180.0f);
|
||||
AddParameter(*m_pAngles);
|
||||
|
||||
m_pVector = new CVariable<Vec3>();
|
||||
m_pVector->SetName("vector");
|
||||
m_pVector->Set(Vec3(0.0f, 0.0f, 0.0f));
|
||||
AddParameter(*m_pVector);
|
||||
|
||||
m_pScale = new CVariable<Vec3>();
|
||||
m_pScale->SetName("scale");
|
||||
m_pScale->Set(Vec3(1.0f, 1.0f, 1.0f));
|
||||
AddParameter(*m_pScale);
|
||||
}
|
||||
|
||||
// CMapperOperator
|
||||
public:
|
||||
virtual QuatT CMapperOperator_Transform::Compute()
|
||||
{
|
||||
QuatT result(IDENTITY);
|
||||
m_pVector->Get(result.t);
|
||||
|
||||
Vec3 scale;
|
||||
m_pScale->Get(scale);
|
||||
|
||||
Vec3 angles;
|
||||
m_pAngles->Get(angles);
|
||||
|
||||
result.q = Quat::CreateRotationXYZ(
|
||||
Ang3(DEG2RAD(angles.x), DEG2RAD(angles.y), DEG2RAD(angles.z)));
|
||||
|
||||
if (CMapperOperator* pOperator = GetPosition(0))
|
||||
{
|
||||
result.t = pOperator->Compute().t.CompMul(scale) + result.t;
|
||||
}
|
||||
if (CMapperOperator* pOperator = GetOrientation(0))
|
||||
{
|
||||
result.q = pOperator->Compute().q * result.q;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
CVariable<Vec3>* m_pVector;
|
||||
CVariable<Vec3>* m_pAngles;
|
||||
CVariable<Vec3>* m_pScale;
|
||||
};
|
||||
|
||||
SkeletonMapperOperatorRegister(Transform, CMapperOperator_Transform)
|
||||
|
||||
class CMapperOperator_PositionsToOrientation
|
||||
: public CMapperOperator
|
||||
{
|
||||
public:
|
||||
CMapperOperator_PositionsToOrientation()
|
||||
: CMapperOperator("PositionsToOrientation", 3, 0)
|
||||
{
|
||||
}
|
||||
|
||||
// CMapperOperator
|
||||
public:
|
||||
virtual QuatT Compute()
|
||||
{
|
||||
CMapperOperator* pOperator0 = GetPosition(0);
|
||||
CMapperOperator* pOperator1 = GetPosition(1);
|
||||
CMapperOperator* pOperator2 = GetPosition(2);
|
||||
if (!pOperator0 || !pOperator1 || !pOperator2)
|
||||
{
|
||||
return QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
Vec3 p0 = pOperator0->Compute().t;
|
||||
Vec3 p1 = pOperator1->Compute().t;
|
||||
Vec3 p2 = pOperator2->Compute().t;
|
||||
|
||||
Vec3 m = (p1 + p2) * 0.5f;
|
||||
Vec3 y = (m - p0).GetNormalized();
|
||||
Vec3 z = (p1 - p2).GetNormalized();
|
||||
Vec3 x = y % z;
|
||||
z = x % y;
|
||||
|
||||
Matrix33 m33;
|
||||
m33.SetFromVectors(x, y, z);
|
||||
QuatT result(IDENTITY);
|
||||
result.q = Quat(m33);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
SkeletonMapperOperatorRegister(PositionsToOrientation, CMapperOperator_PositionsToOrientation)
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../Util/Variable.h"
|
||||
|
||||
#undef GetClassName
|
||||
|
||||
#define SkeletonMapperOperatorRegister(name, className) \
|
||||
class CMapperOperatorDesc_##name \
|
||||
: public CMapperOperatorDesc \
|
||||
{ \
|
||||
public: \
|
||||
CMapperOperatorDesc_##name() \
|
||||
: CMapperOperatorDesc(#name) { } \
|
||||
protected: \
|
||||
virtual const char* GetName() { return #name; } \
|
||||
virtual CMapperOperator* Create() { return new className(); } \
|
||||
} mapperOperatorDesc__##name;
|
||||
|
||||
namespace Skeleton {
|
||||
class CMapperOperator;
|
||||
|
||||
class CMapperOperatorDesc
|
||||
{
|
||||
public:
|
||||
static uint32 GetCount() { return uint32(s_descs.size()); }
|
||||
static const char* GetName(uint32 index) { return s_descs[index]->GetName(); }
|
||||
static CMapperOperator* Create(uint32 index) { return s_descs[index]->Create(); }
|
||||
|
||||
private:
|
||||
static std::vector<CMapperOperatorDesc*> s_descs;
|
||||
|
||||
public:
|
||||
CMapperOperatorDesc(const char* name);
|
||||
|
||||
protected:
|
||||
virtual const char* GetName() = 0;
|
||||
virtual CMapperOperator* Create() = 0;
|
||||
};
|
||||
|
||||
class CMapperOperator
|
||||
: public _reference_target_t
|
||||
{
|
||||
protected:
|
||||
CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount);
|
||||
~CMapperOperator();
|
||||
|
||||
public:
|
||||
const char* GetClassName() { return m_className; }
|
||||
|
||||
uint32 GetPositionCount() const { return uint32(m_position.size()); }
|
||||
void SetPosition(uint32 index, CMapperOperator* pOperator) { m_position[index] = pOperator; }
|
||||
CMapperOperator* GetPosition(uint32 index) { return m_position[index]; }
|
||||
|
||||
uint32 GetOrientationCount() const { return uint32(m_orientation.size()); }
|
||||
void SetOrientation(uint32 index, CMapperOperator* pOperator) { m_orientation[index] = pOperator; }
|
||||
CMapperOperator* GetOrientation(uint32 index) { return m_orientation[index]; }
|
||||
|
||||
uint32 GetParameterCount() { return uint32(m_parameters.size()); }
|
||||
IVariable* GetParameter(uint32 index) { return m_parameters[index]; }
|
||||
|
||||
bool IsOfClass(const char* className);
|
||||
uint32 HasLinksOfClass(const char* className);
|
||||
|
||||
bool SerializeTo(XmlNodeRef& node);
|
||||
bool SerializeFrom(XmlNodeRef& node);
|
||||
|
||||
bool SerializeWithLinksTo(XmlNodeRef& node);
|
||||
bool SerializeWithLinksFrom(XmlNodeRef& node);
|
||||
|
||||
protected:
|
||||
void AddParameter(IVariable& variable) { m_parameters.push_back(&variable); }
|
||||
|
||||
public:
|
||||
virtual QuatT Compute() = 0;
|
||||
|
||||
private:
|
||||
const char* m_className;
|
||||
std::vector<_smart_ptr<CMapperOperator> > m_position;
|
||||
std::vector<_smart_ptr<CMapperOperator> > m_orientation;
|
||||
|
||||
std::vector<IVariablePtr> m_parameters;
|
||||
};
|
||||
|
||||
class CMapperLocation
|
||||
: public CMapperOperator
|
||||
{
|
||||
public:
|
||||
CMapperLocation()
|
||||
: CMapperOperator("Location", 0, 0)
|
||||
{
|
||||
m_pName = new CVariable<CString>();
|
||||
m_pName->SetName("name");
|
||||
m_pName->SetFlags(m_pName->GetFlags() | IVariable::UI_INVISIBLE);
|
||||
AddParameter(*m_pName);
|
||||
|
||||
m_pAxis = new CVariable<Vec3>();
|
||||
m_pAxis->SetName("axis");
|
||||
m_pAxis->SetLimits(-3.0f, +3.0f);
|
||||
m_pAxis->Set(Vec3(1.0f, 2.0f, 3.0f));
|
||||
AddParameter(*m_pAxis);
|
||||
|
||||
m_location = QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
public:
|
||||
void SetName(const char* name) { m_pName->Set(name); }
|
||||
CString GetName() const { CString s; m_pName->Get(s); return s; }
|
||||
|
||||
void SetLocation(const QuatT& location) { m_location = location; }
|
||||
const QuatT& GetLocation() const { return m_location; }
|
||||
|
||||
// CMapperOperator
|
||||
public:
|
||||
virtual QuatT Compute()
|
||||
{
|
||||
Vec3 axis;
|
||||
m_pAxis->Get(axis);
|
||||
|
||||
uint32 x = fabs_tpl(axis.x);
|
||||
uint32 y = fabs_tpl(axis.y);
|
||||
uint32 z = fabs_tpl(axis.z);
|
||||
if (x < 1 || y < 1 || z < 1 ||
|
||||
x > 3 || y > 3 || y > 3 ||
|
||||
x == y || x == z || y == z)
|
||||
{
|
||||
return QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
Matrix33 matrix;
|
||||
matrix.SetFromVectors(
|
||||
m_location.q.GetColumn(x - 1) * f32(::sgn(axis.x)),
|
||||
m_location.q.GetColumn(y - 1) * f32(::sgn(axis.y)),
|
||||
m_location.q.GetColumn(z - 1) * f32(::sgn(axis.z)));
|
||||
if (!matrix.IsOrthonormalRH(0.01f))
|
||||
{
|
||||
return QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
QuatT result = m_location;
|
||||
result.q = Quat(matrix);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
CVariable<CString>* m_pName;
|
||||
CVariable<Vec3>* m_pAxis;
|
||||
|
||||
QuatT m_location;
|
||||
};
|
||||
} // namespace Skeleton
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
|
||||
Reference in New Issue
Block a user