metaforce/Runtime/GuiSys/CGuiObject.cpp

167 lines
3.8 KiB
C++
Raw Normal View History

2016-03-10 03:47:37 +00:00
#include "CGuiObject.hpp"
2016-03-17 02:18:01 +00:00
#include "CGuiWidgetDrawParms.hpp"
2016-03-30 20:44:19 +00:00
#include "Graphics/CTexture.hpp"
2016-03-10 03:47:37 +00:00
namespace urde
{
2016-03-11 00:23:16 +00:00
CGuiObject::~CGuiObject()
{
delete x74_child;
delete x78_nextSibling;
}
2016-03-10 03:47:37 +00:00
void CGuiObject::Update(float dt)
{
if (x74_child)
x74_child->Update(dt);
if (x78_nextSibling)
x78_nextSibling->Update(dt);
}
void CGuiObject::Draw(const CGuiWidgetDrawParms& parms) const
{
if (x74_child)
x74_child->Draw(parms);
if (x78_nextSibling)
x78_nextSibling->Draw(parms);
}
void CGuiObject::MoveInWorld(const zeus::CVector3f& vec)
{
if (x70_parent)
x70_parent->RotateW2O(vec);
2016-04-29 10:08:46 +00:00
x4_localXF.origin += vec;
2016-03-10 03:47:37 +00:00
Reorthogonalize();
RecalculateTransforms();
}
2016-03-14 00:58:19 +00:00
void CGuiObject::SetLocalPosition(const zeus::CVector3f& pos)
{
2016-04-29 10:08:46 +00:00
MoveInWorld(pos - x4_localXF.origin);
2016-03-14 00:58:19 +00:00
}
2016-03-10 03:47:37 +00:00
void CGuiObject::RotateReset()
{
2016-04-29 10:08:46 +00:00
x4_localXF.basis = zeus::CMatrix3f::skIdentityMatrix3f;
2016-03-11 00:23:16 +00:00
Reorthogonalize();
RecalculateTransforms();
2016-03-10 03:47:37 +00:00
}
zeus::CVector3f CGuiObject::RotateW2O(const zeus::CVector3f& vec) const
{
2016-03-11 00:23:16 +00:00
return x34_worldXF.transposeRotate(vec);
2016-03-10 03:47:37 +00:00
}
zeus::CVector3f CGuiObject::RotateO2P(const zeus::CVector3f& vec) const
{
2016-03-11 00:23:16 +00:00
return x4_localXF.rotate(vec);
2016-03-10 03:47:37 +00:00
}
zeus::CVector3f CGuiObject::RotateTranslateW2O(const zeus::CVector3f& vec) const
{
2016-04-29 10:08:46 +00:00
return x34_worldXF.transposeRotate(vec - x34_worldXF.origin);
2016-03-10 03:47:37 +00:00
}
void CGuiObject::MultiplyO2P(const zeus::CTransform& xf)
{
2016-04-29 10:08:46 +00:00
x4_localXF.origin += x64_rotationCenter;
2016-03-10 03:47:37 +00:00
x4_localXF = xf * x4_localXF;
2016-04-29 10:08:46 +00:00
x4_localXF.origin -= x64_rotationCenter;
2016-03-10 03:47:37 +00:00
Reorthogonalize();
RecalculateTransforms();
}
2016-03-11 00:23:16 +00:00
void CGuiObject::AddChildObject(CGuiObject* obj, bool makeWorldLocal, bool atEnd)
2016-03-10 03:47:37 +00:00
{
obj->x70_parent = this;
if (!x74_child)
{
x74_child = obj;
}
else if (atEnd)
{
CGuiObject* prev = nullptr;
CGuiObject* cur = x74_child;
for (; cur ; cur = cur->x78_nextSibling) {prev = cur;}
if (prev)
prev->x78_nextSibling = obj;
}
else
{
obj->x78_nextSibling = x74_child;
x74_child = obj;
}
2016-03-11 00:23:16 +00:00
if (makeWorldLocal)
2016-03-10 03:47:37 +00:00
{
2016-04-29 10:08:46 +00:00
zeus::CVector3f negParentWorld = -x34_worldXF.origin;
2016-03-11 00:23:16 +00:00
zeus::CMatrix3f basisMat(
2016-04-29 10:08:46 +00:00
x34_worldXF.basis[0] / x34_worldXF.basis[0].magnitude(),
x34_worldXF.basis[1] / x34_worldXF.basis[1].magnitude(),
x34_worldXF.basis[2] / x34_worldXF.basis[2].magnitude());
2016-03-11 00:23:16 +00:00
zeus::CVector3f xfWorld = basisMat * negParentWorld;
obj->x4_localXF = zeus::CTransform(basisMat, xfWorld) * obj->x34_worldXF;
2016-03-10 03:47:37 +00:00
}
RecalculateTransforms();
}
CGuiObject* CGuiObject::RemoveChildObject(CGuiObject* obj, bool makeWorldLocal)
{
CGuiObject* prev = nullptr;
CGuiObject* cur = x74_child;
for (; cur && cur != obj ; cur = cur->x78_nextSibling) {prev = cur;}
if (!cur)
return nullptr;
if (prev)
prev->x78_nextSibling = cur->x78_nextSibling;
cur->x78_nextSibling = nullptr;
cur->x70_parent = nullptr;
if (makeWorldLocal)
cur->x4_localXF = cur->x34_worldXF;
cur->RecalculateTransforms();
return cur;
}
void CGuiObject::RecalculateTransforms()
{
if (x70_parent)
{
2016-04-29 10:08:46 +00:00
x4_localXF.origin += x64_rotationCenter;
2016-03-10 03:47:37 +00:00
x34_worldXF = x70_parent->x34_worldXF * x4_localXF;
2016-04-29 10:08:46 +00:00
x4_localXF.origin -= x64_rotationCenter;
x34_worldXF.origin -= x64_rotationCenter;
2016-03-10 03:47:37 +00:00
}
else
{
x34_worldXF = x4_localXF;
}
if (x78_nextSibling)
x78_nextSibling->RecalculateTransforms();
if (x74_child)
x74_child->RecalculateTransforms();
}
void CGuiObject::Reorthogonalize()
{
static bool Global = false;
if (Global)
{
x4_localXF.orthonormalize();
RecalculateTransforms();
}
}
void CGuiObject::SetO2WTransform(const zeus::CTransform& xf)
{
x4_localXF = GetParent()->x34_worldXF.inverse() * xf;
RecalculateTransforms();
}
}