// @(#)root/gl:$Name: $:$Id: TGLBoundingBox.h,v 1.5 2005/06/21 16:54:17 brun Exp $
// Author: Richard Maunder 25/05/2005
/*************************************************************************
* Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGLBoundingBox
#define ROOT_TGLBoundingBox
#ifndef ROOT_TGLUtil
#include "TGLUtil.h"
#endif
/*************************************************************************
* TGLBoundingBox - TODO
*
*
*
*************************************************************************/
// TODO: Create more compact version + axis aligned version, both with lazy
// sphere testing.
class TGLBoundingBox
{
private:
// Fields
// Box vertices are indexed thus:
//
// 7-------6
// /| /|
// 3-------2 |
// | 4-----|-5
// |/ |/
// 0-------1
//
// 0123 near face
// 4567 far face
//
// This could be more compact: 3 vertices which form plane cutting
// box diagonally (e.g. 0,5,6 or 1,3,6 etc) would fix it in space - rest
// could be calculated on demand - but not worth effort.....
TGLVertex3 fVertex[8]; //! the 8 bounding box vertices
Double_t fVolume; //! box volume - cached for speed
// Methods
void UpdateVolume();
Bool_t ValidIndex(UInt_t index) const { return (index < 8); }
Double_t Min(UInt_t index) const;
Double_t Max(UInt_t index) const;
public:
TGLBoundingBox();
TGLBoundingBox(const TGLVertex3 vertex[8]);
TGLBoundingBox(const Double_t vertex[8][3]);
TGLBoundingBox(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex);
TGLBoundingBox(const TGLBoundingBox & other);
virtual ~TGLBoundingBox(); // ClassDef introduces virtual fns
// Set orientated BB
TGLBoundingBox & operator=(const TGLBoundingBox & other) { Set(other); return *this; }
void Set(const TGLVertex3 vertex[8]);
void Set(const Double_t vertex[8][3]);
void Set(const TGLBoundingBox & other);
void SetEmpty();
// Set orientated AA
void SetAligned(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex); // axis aligned
void SetAligned(UInt_t nbPnts, const Double_t * pnts); // axis aligned
void Transform(const TGLMatrix & matrix);
void Scale(Double_t val);
void Translate(const TGLVector3 & offset);
inline const TGLVertex3 & operator [] (UInt_t index) const;
Double_t XMin() const { return Min(0); }
Double_t XMax() const { return Max(0); }
Double_t YMin() const { return Min(1); }
Double_t YMax() const { return Max(1); }
Double_t ZMin() const { return Min(2); }
Double_t ZMax() const { return Max(2); }
inline TGLVertex3 Center() const;
inline TGLVector3 Extents() const;
inline TGLVector3 Axis(UInt_t i, Bool_t normalised = true) const;
inline Double_t Volume() const { return fVolume; }
inline Bool_t IsEmpty() const;
EOverlap Overlap(const TGLPlane & plane) const;
Bool_t AlignedContains(const TGLBoundingBox & other) const; // we MUST be axis aligned
static Bool_t Intersect(const TGLBoundingBox & a, const TGLBoundingBox & b);
void Draw() const;
void Dump() const;
ClassDef(TGLBoundingBox,0); // a 3D orientated bounding box
};
//______________________________________________________________________________
inline const TGLVertex3 & TGLBoundingBox::operator [] (UInt_t index) const
{
if (ValidIndex(index)) {
return fVertex[index];
} else {
assert(kFALSE);
return fVertex[0];
}
}
//______________________________________________________________________________
inline TGLVector3 TGLBoundingBox::Extents() const
{
return TGLVector3(Axis(0,kFALSE).Mag(),
Axis(1,kFALSE).Mag(),
Axis(2,kFALSE).Mag());
}
//______________________________________________________________________________
inline TGLVertex3 TGLBoundingBox::Center() const
{
TGLVector3 v = fVertex[6] - fVertex[0];
return fVertex[0] + v/2.0;
}
//______________________________________________________________________________
inline TGLVector3 TGLBoundingBox::Axis(UInt_t i, Bool_t normalised) const
{
// 7-------6
// /| /|
// 3-------2 |
// | 4-----|-5
// |/ |/
// 0-------1
TGLVector3 axis;
if (i == 0) {
axis.Set(fVertex[1] - fVertex[0]);
} else if (i == 1) {
axis.Set(fVertex[3] - fVertex[0]);
} else if (i == 2) {
axis.Set(fVertex[4] - fVertex[0]);
} else {
assert(kFALSE);
}
if (normalised) {
axis.Normalise();
}
return axis;
}
//______________________________________________________________________________
inline void TGLBoundingBox::UpdateVolume()
{
TGLVector3 extents = Extents();
fVolume = fabs(extents.X() * extents.Y() * extents.Z());
}
inline Bool_t TGLBoundingBox::IsEmpty() const
{
// TODO: Round errors - should have epsilon test
return (Volume() == 0.0);
}
#endif // ROOT_TGLBoundingBox
syntax highlighted by Code2HTML, v. 0.9.1