You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/Animation/SkeletonMapperOperator.cpp

285 lines
6.1 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* 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, nullptr);
m_orientation.resize(orientationCount, nullptr);
}
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)