225 lines
3.3 KiB
C++
225 lines
3.3 KiB
C++
#include "dl_coor.h"
|
|
|
|
#include <cassert>
|
|
#include "io/dl_log.h"
|
|
|
|
namespace dl
|
|
{
|
|
Coor* Coor::Create(Coor* parent /*= nullptr*/)
|
|
{
|
|
Coor* ret = new Coor;
|
|
ret->SetParent(parent);
|
|
return ret;
|
|
}
|
|
|
|
Coor* Coor::Clone()
|
|
{
|
|
assert(_rootIndex == -1);
|
|
|
|
Coor* ret = new Coor(*this);
|
|
return ret;
|
|
}
|
|
|
|
void Coor::DtPosition(const Position& dt)
|
|
{
|
|
_position += dt;
|
|
}
|
|
|
|
void Coor::DtScale(const Position& dt)
|
|
{
|
|
_scale += dt;
|
|
}
|
|
|
|
void Coor::DtScale(Float dt)
|
|
{
|
|
DtScale({ dt,dt });
|
|
}
|
|
|
|
|
|
void Coor::DtRotate(Float dt)
|
|
{
|
|
_rotate += dt;
|
|
_cosR = std::cos(_rotate);
|
|
_sinRNag = -std::sin(_rotate);
|
|
}
|
|
|
|
|
|
void Coor::SetPosition(const Position& pos)
|
|
{
|
|
_position = pos;
|
|
}
|
|
|
|
|
|
void Coor::SetScale(const Position& scale)
|
|
{
|
|
assert(scale[0] && scale[1]);
|
|
_scale = scale;
|
|
}
|
|
|
|
void Coor::SetRotate(Float rotate)
|
|
{
|
|
_rotate = rotate;
|
|
_cosR = std::cos(_rotate);
|
|
_sinRNag = -std::sin(_rotate);
|
|
}
|
|
|
|
void Coor::SetParent(Coor* coor)
|
|
{
|
|
if (this == coor)
|
|
{
|
|
log("自己不能设置父坐标系为自己!");
|
|
return;
|
|
}
|
|
if (_rootIndex != -1)
|
|
{
|
|
log("根坐标系不能设置父坐标系!");
|
|
return;
|
|
}
|
|
_parent = coor;
|
|
}
|
|
|
|
Position Coor::GetPosition() const
|
|
{
|
|
return _position;
|
|
}
|
|
|
|
Position Coor::GetScale() const
|
|
{
|
|
return _scale;
|
|
}
|
|
|
|
Float Coor::GetRotate() const
|
|
{
|
|
return _rotate;
|
|
}
|
|
|
|
Coor* Coor::GetParent() const
|
|
{
|
|
return _parent;
|
|
}
|
|
|
|
Position Coor::ThisToParent(Position pos) const
|
|
{
|
|
// 先旋转、再缩放、位移
|
|
if (_rotate)
|
|
{
|
|
// cos(-x) <=> cos(x)
|
|
// sin(-x) <=> -sin(x)
|
|
Float cos_a = _cosR * pos[0];
|
|
Float cos_b = _cosR * pos[1];
|
|
Float sin_a = _sinRNag * pos[0];
|
|
Float sin_b = _sinRNag * pos[1];
|
|
|
|
pos[0] = cos_a + sin_b;
|
|
pos[1] = cos_b - sin_a;
|
|
}
|
|
|
|
if (_scale[0] != 1.0f)
|
|
pos[0] *= _scale[0];
|
|
if (_scale[1] != 1.0f)
|
|
pos[1] *= _scale[1];
|
|
|
|
pos += _position;
|
|
|
|
return pos;
|
|
}
|
|
|
|
|
|
|
|
Position Coor::ParentToThis(Position pos) const
|
|
{
|
|
pos -= _position;
|
|
|
|
if (_scale[0] != 1.0)
|
|
pos[0] /= _scale[0];
|
|
if (_scale[1] != 1.0)
|
|
pos[1] /= _scale[1];
|
|
|
|
// 相反
|
|
if (_rotate)
|
|
{
|
|
Float cos_a = _cosR * pos[0];
|
|
Float cos_b = _cosR * pos[1];
|
|
Float sin_a = -_sinRNag * pos[0];
|
|
Float sin_b = -_sinRNag * pos[1];
|
|
|
|
pos[0] = cos_a + sin_b;
|
|
pos[1] = cos_b - sin_a;
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
|
|
Position Coor::ThisToWorld(Position pos) const
|
|
{
|
|
// 有parent,则转换到parent,直到没有
|
|
const Coor* coor = this;
|
|
while (coor->_parent)
|
|
{
|
|
pos = coor->ThisToParent(pos);
|
|
coor = coor->_parent;
|
|
}
|
|
return coor->ThisToParent(pos);
|
|
}
|
|
|
|
Position Coor::WorldToThis(Position pos) const
|
|
{
|
|
std::array<const Coor*, 32> stack;
|
|
size_t i = 0;
|
|
const Coor* coor = this;
|
|
|
|
stack[i++] = coor;
|
|
while (coor->_parent)
|
|
{
|
|
stack[i++] = coor->_parent;
|
|
coor = coor->_parent;
|
|
}
|
|
|
|
while (i > 0)
|
|
{
|
|
coor = stack[--i];
|
|
pos = coor->ParentToThis(pos);
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
Position Coor::ThisToRoot(Position pos) const
|
|
{
|
|
// 是根节点,或者判断其父亲,直到没有parent
|
|
if (_rootIndex != -1)
|
|
return pos;
|
|
|
|
pos = ThisToParent(pos);
|
|
const Coor* coor = _parent;
|
|
|
|
//
|
|
while (coor && coor->_rootIndex == -1)
|
|
{
|
|
pos = coor->ThisToParent(pos);
|
|
coor = coor->_parent;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
Coor* Coor::GetRoot()
|
|
{
|
|
// 是根节点,或者判断其父亲,直到没有parent
|
|
if (_rootIndex != -1)
|
|
return this;
|
|
|
|
Coor* coor = _parent;
|
|
|
|
//
|
|
while (coor)
|
|
{
|
|
if (coor->_rootIndex != -1)
|
|
return coor;
|
|
|
|
coor = coor->_parent;
|
|
}
|
|
return coor;
|
|
}
|
|
|
|
}
|
|
|