git mv Code\Sandbox\Editor Code/Editor

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2021-06-29 12:41:59 -07:00
parent 9f0bbf3b74
commit e34e36cb35
1415 changed files with 0 additions and 0 deletions
@@ -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
+148
View File
@@ -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;
}
+56
View File
@@ -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
+367
View File
@@ -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;
}
+75
View File
@@ -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