/*////////////////////////////////////////////////////////////////////////////// // 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 "Math/Dense.h" #include "Math/Transform.h" #include #include 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 { public: uLibTypeMacro(ContainerBox, TRS) virtual const char * GetClassName() const override { return "ContainerBox"; } //////////////////////////////////////////////////////////////////////////// // PROPERTIES // Vector3f Size; Vector3f Origin; /** * @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) { ULIB_ACTIVATE_PROPERTIES(*this); 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) { ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } /** * @brief Copy constructor. * @param copy The ContainerBox instance to copy from. */ ContainerBox(const ContainerBox ©) : m_LocalT(this), // Reset parent to the new object TRS(copy), Size(copy.Size), Origin(copy.Origin) { ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } /** * @brief Serialization template for property registration and persistence. */ template void serialize(ArchiveT & ar, const unsigned int version) { ar & HRP(Size); ar & HRP(Origin); ar & NVP("TRS", boost::serialization::base_object(*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: AffineTransform m_LocalT; }; } // namespace uLib #endif // CONTAINERBOX_H