245 lines
7.1 KiB
C++
245 lines
7.1 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 "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 {
|
|
|
|
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 <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:
|
|
AffineTransform m_LocalT;
|
|
};
|
|
|
|
} // namespace uLib
|
|
|
|
#endif // CONTAINERBOX_H
|