refactor: update Puppet transform logic to support AffineTransform world matrices and improve selection highlighting

This commit is contained in:
AndreaRigoni
2026-03-30 15:24:37 +00:00
parent 46c39bc26e
commit 22d0041942
24 changed files with 469 additions and 331 deletions

View File

@@ -35,12 +35,22 @@
namespace uLib {
class Geometry : public AffineTransform {
class Geometry : virtual public Object {
protected:
Geometry* m_Parent = nullptr;
public:
uLibTypeMacro(Geometry, AffineTransform)
uLibTypeMacro(Geometry, Object)
virtual const char * GetClassName() const override { return "Geometry"; }
virtual void SetParent(Geometry* p) { m_Parent = p; }
virtual Geometry* GetParent() const { return m_Parent; }
virtual bool IsLinear() const { return false; }
virtual bool IsPure() const { return false; }
virtual Vector3f ToLinear(const Vector3f& curved_space) const {
return curved_space;
}
@@ -49,38 +59,120 @@ public:
return cartesian_space;
}
inline Vector4f GetWorldPoint(const Vector4f v) const {
Vector3f lin = ToLinear(Vector3f(v.x(), v.y(), v.z()));
return this->GetWorldMatrix() * Vector4f(lin.x(), lin.y(), lin.z(), v.w());
virtual Vector4f GetWorldPoint(const Vector4f v) const = 0;
virtual Vector4f GetLocalPoint(const Vector4f v) const = 0;
virtual Vector4f GetWorldPoint(const float x, const float y, const float z) const {
return GetWorldPoint(Vector4f(x,y,z,1));
}
inline Vector4f GetWorldPoint(const float x, const float y, const float z) {
return this->GetWorldPoint(Vector4f(x,y,z,1));
virtual Vector4f GetLocalPoint(const float x, const float y, const float z) const {
return GetLocalPoint(Vector4f(x,y,z,1));
}
inline Vector4f GetLocalPoint(const Vector4f v) const {
Vector4f loc_lin = this->GetWorldMatrix().inverse() * v;
Vector3f curv = FromLinear(Vector3f(loc_lin.x(), loc_lin.y(), loc_lin.z()));
return Vector4f(curv.x(), curv.y(), curv.z(), loc_lin.w());
virtual Vector4f GetWorldPoint(const Vector3f v) const {
return GetWorldPoint(Vector4f(v.x(), v.y(), v.z(), 1.0f));
}
inline Vector4f GetLocalPoint(const float x, const float y, const float z) {
return this->GetLocalPoint(Vector4f(x,y,z,1));
virtual Vector4f GetLocalPoint(const Vector3f v) const {
return GetLocalPoint(Vector4f(v.x(), v.y(), v.z(), 1.0f));
}
virtual void Translate(Vector3f t) = 0;
virtual void Rotate(Vector3f r) = 0;
virtual void Scale(Vector3f s) = 0;
};
class CylindricalGeometry : public Geometry {
class LinearGeometry : public Geometry {
protected:
Affine3f m_T = Affine3f::Identity();
public:
uLibTypeMacro(CylindricalGeometry, Geometry)
uLibTypeMacro(LinearGeometry, Geometry)
virtual const char * GetClassName() const override { return "LinearGeometry"; }
virtual bool IsLinear() const override { return true; }
virtual bool IsPure() const override { return true; }
virtual Vector4f GetWorldPoint(const Vector4f v) const override {
Vector3f lin_v = ToLinear(v.head<3>());
Vector4f v_lin(lin_v.x(), lin_v.y(), lin_v.z(), v.w());
Affine3f combined = m_T;
const Geometry* curr = m_Parent;
while (curr && curr->IsLinear() && curr->IsPure()) {
combined = static_cast<const LinearGeometry*>(curr)->m_T * combined;
curr = curr->GetParent();
}
Vector4f v_res = combined.matrix() * v_lin;
if (curr) return curr->GetWorldPoint(v_res);
return v_res;
}
virtual Vector4f GetLocalPoint(const Vector4f v) const override {
Vector4f v_parent = m_Parent ? m_Parent->GetLocalPoint(v) : v;
Vector4f v_loc_lin = m_T.inverse().matrix() * v_parent;
Vector3f v_curv = FromLinear(v_loc_lin.head<3>());
return Vector4f(v_curv.x(), v_curv.y(), v_curv.z(), v_loc_lin.w());
}
virtual void Translate(Vector3f t) override {
m_T.translate(t);
}
virtual void Rotate(Vector3f r) override {
this->EulerYZYRotate(r);
}
virtual void Scale(Vector3f s) override {
m_T.scale(s);
}
void SetPosition(const Vector3f& v) { m_T.translation() = v; }
Vector3f GetPosition() const { return m_T.translation(); }
void EulerYZYRotate(const Vector3f& e) {
Matrix3f mat;
mat = Eigen::AngleAxisf(e.x(), Vector3f::UnitY())
* Eigen::AngleAxisf(e.y(), Vector3f::UnitZ())
* Eigen::AngleAxisf(e.z(), Vector3f::UnitY());
m_T.rotate(mat);
}
void FlipAxes(int first, int second) {
Matrix3f mat = Matrix3f::Identity();
mat.col(first).swap(mat.col(second));
m_T.rotate(mat);
}
const Affine3f& GetTransform() const { return m_T; }
void SetTransform(const Affine3f& t) { m_T = t; }
};
class CylindricalGeometry : public LinearGeometry {
public:
uLibTypeMacro(CylindricalGeometry, LinearGeometry)
CylindricalGeometry() {}
Vector3f ToLinear(const Vector3f& cylindrical) const {
virtual const char * GetClassName() const override { return "CylindricalGeometry"; }
virtual bool IsPure() const override { return false; }
Vector3f ToLinear(const Vector3f& cylindrical) const override {
return Vector3f(cylindrical.x() * std::cos(cylindrical.y()),
cylindrical.x() * std::sin(cylindrical.y()),
cylindrical.z());
}
Vector3f FromLinear(const Vector3f& linear) const {
Vector3f FromLinear(const Vector3f& linear) const override {
float r = std::sqrt(linear.x() * linear.x() + linear.y() * linear.y());
float phi = std::atan2(linear.y(), linear.x());
return Vector3f(r, phi, linear.z());
@@ -88,14 +180,16 @@ public:
};
class SphericalGeometry : public Geometry {
class SphericalGeometry : public LinearGeometry {
public:
uLibTypeMacro(SphericalGeometry, Geometry)
uLibTypeMacro(SphericalGeometry, LinearGeometry)
SphericalGeometry() {}
virtual const char * GetClassName() const override { return "SphericalGeometry"; }
Vector3f ToLinear(const Vector3f& spherical) const {
virtual bool IsPure() const override { return false; }
Vector3f ToLinear(const Vector3f& spherical) const override {
float r = spherical.x();
float theta = spherical.y();
float phi = spherical.z();
@@ -104,7 +198,7 @@ public:
r * std::cos(theta));
}
Vector3f FromLinear(const Vector3f& linear) const {
Vector3f FromLinear(const Vector3f& linear) const override {
float r = linear.norm();
float theta = (r == 0.0f) ? 0.0f : std::acos(linear.z() / r);
float phi = std::atan2(linear.y(), linear.x());
@@ -113,14 +207,16 @@ public:
};
class ToroidalGeometry : public Geometry {
class ToroidalGeometry : public LinearGeometry {
public:
uLibTypeMacro(ToroidalGeometry, Geometry)
uLibTypeMacro(ToroidalGeometry, LinearGeometry)
ToroidalGeometry(float Rtor) : m_Rtor(Rtor) {}
virtual const char * GetClassName() const override { return "ToroidalGeometry"; }
Vector3f ToLinear(const Vector3f& toroidal) const {
virtual bool IsPure() const override { return false; }
Vector3f ToLinear(const Vector3f& toroidal) const override {
float r = toroidal.x();
float theta = toroidal.y();
float phi = toroidal.z();
@@ -129,7 +225,7 @@ public:
r * std::sin(theta));
}
Vector3f FromLinear(const Vector3f& linear) const {
Vector3f FromLinear(const Vector3f& linear) const override {
float phi = std::atan2(linear.y(), linear.x());
float r_xy = std::sqrt(linear.x() * linear.x() + linear.y() * linear.y());
float delta_r = r_xy - m_Rtor;