Files
uLib/src/Math/ContainerBox.h

242 lines
6.9 KiB
C++

/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CONTAINERBOX_H
#define U_CONTAINERBOX_H
#include "Geometry.h"
#include "Core/Object.h"
#include "Core/Property.h"
#include "Core/Serializable.h"
#include "Math/Dense.h"
#include "Math/Transform.h"
#include <utility>
#include <iostream>
namespace uLib {
/**
* @brief Represents an oriented bounding box (OBB) within a hierarchical
* transformation system.
*
* ContainerBox inherits from TRS, which defines its parent
* coordinate system. It contains an internal local transformation (m_LocalT)
* that defines the box's specific origin and size relative to its own
* coordinate system.
*/
class ContainerBox : public TRS {
uLibTypeMacro(ContainerBox, TRS)
ULIB_SERIALIZE_ACCESS
ULIB_DECLARE_PROPERTIES(ContainerBox)
public:
/**
* @brief Default constructor.
* Initializes the local transformation with this instance as its parent.
*/
ContainerBox()
: m_LocalT(this), // BaseClass is Parent of m_LocalTransform
Size(1.0f, 1.0f, 1.0f),
Origin(0.0f, 0.0f, 0.0f) {
this->Sync();
}
/**
* @brief Constructor with size.
* @param size The size vector.
*/
ContainerBox(const Vector3f &size)
: m_LocalT(this),
Size(size),
Origin(0.0f, 0.0f, 0.0f) {
this->Sync();
}
/**
* @brief Copy constructor.
* @param copy The ContainerBox instance to copy from.
*/
ContainerBox(const ContainerBox &copy)
: m_LocalT(this), // Reset parent to the new object
TRS(copy),
Size(copy.Size),
Origin(copy.Origin) {
this->Sync();
}
// /**
// * @brief Serialization template for property registration and persistence.
// */
template <class ArchiveT>
void serialize(ArchiveT & ar, const unsigned int version) {
ar & HRP(Size);
ar & HRP(Origin);
ar & NVP("TRS", boost::serialization::base_object<TRS>(*this));
}
/**
* @brief Sets the box origin relative to its coordinate system.
* @param v The origin position vector.
*/
void SetOrigin(const Vector3f &v) {
Origin = v;
m_LocalT.SetPosition(v);
}
/**
* @brief Gets the box origin relative to its coordinate system.
* @return The origin position vector.
*/
Vector3f GetOrigin() const { return m_LocalT.GetPosition(); }
/**
* @brief Sets the size of the box.
* Re-initializes the local transformation and applies the new scale.
* @param v The size vector (width, height, depth).
*/
void SetSize(const Vector3f &v) {
Size = v;
Vector3f pos = this->GetOrigin();
m_LocalT = AffineTransform(this); // regenerate local transform
m_LocalT.Scale(v);
m_LocalT.SetPosition(pos);
}
/**
* @brief Gets the current size (scale) of the box.
* @return The size vector.
*/
Vector3f GetSize() const {
Vector3f s = this->GetScale();
Vector3f ls = m_LocalT.GetScale();
return Vector3f(s(0) * ls(0), s(1) * ls(1), s(2) * ls(2));
}
/**
* @brief Swaps two local axes of the box.
* @param first Index of the first axis (0=X, 1=Y, 2=Z).
* @param second Index of the second axis (0=X, 1=Y, 2=Z).
*/
void FlipLocalAxes(int first, int second) {
m_LocalT.FlipAxes(first, second);
}
/**
* @brief Returns the world transformation matrix of the box's volume.
* @return A 4x4 transformation matrix.
*/
Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); }
/**
* @brief Returns the local transformation matrix of the box's volume.
* @return A 4x4 transformation matrix.
*/
Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); }
/**
* @brief Transforms a point from box-local space to world space.
* @param v The local point (4D homogeneous vector).
* @return The transformed point in world space.
*/
Vector4f GetWorldPoint(const Vector4f &v) const {
return m_LocalT.GetWorldMatrix() * v;
}
/**
* @brief Transforms a point from box-local space coordinates to world space.
* @param x X coordinate in local space.
* @param y Y coordinate in local space.
* @param z Z coordinate in local space.
* @return The transformed point in world space.
*/
Vector4f GetWorldPoint(const float x, const float y, const float z) {
return this->GetWorldPoint(Vector4f(x, y, z, 1));
}
/**
* @brief Transforms a point from world space to box-local space.
* @param v The world point (4D homogeneous vector).
* @return The transformed point in box-local space.
*/
Vector4f GetLocalPoint(const Vector4f &v) const {
return m_LocalT.GetWorldMatrix().inverse() * v;
}
/**
* @brief Transforms a point from world space coordinates to box-local space.
* @param x X coordinate in world space.
* @param y Y coordinate in world space.
* @param z Z coordinate in world space.
* @return The transformed point in box-local space.
*/
Vector4f GetLocalPoint(const float x, const float y, const float z) {
return this->GetLocalPoint(Vector4f(x, y, z, 1));
}
/** Translate using transformation chain */
using AffineTransform::Translate;
/** Rotate using transformation chain */
using AffineTransform::Rotate;
/** Scale using transformation chain */
using AffineTransform::Scale;
signals:
/** Signal emitted when properties change */
virtual void Updated() override {
// 1. Synchronize local box part (Size/Origin -> m_LocalT)
this->Sync();
// 2. Synchronize TRS part (position/rotation/scaling -> m_T) and emit signal
this->TRS::Updated();
// std::cout << "ContainerBox::Updated()" << std::endl;
}
private:
/** Synchronizes internal transformation with properties */
void Sync() {
this->SetOrigin(Origin);
this->SetSize(Size);
}
private:
Vector3f Size;
Vector3f Origin;
AffineTransform m_LocalT;
};
} // namespace uLib
#endif // CONTAINERBOX_H