Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:29:52

0001 // @(#)root/gl:$Id$
0002 // Author:  Richard Maunder  25/05/2005
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TGLBoundingBox
0013 #define ROOT_TGLBoundingBox
0014 
0015 #include "TGLUtil.h"
0016 
0017 #include <vector>
0018 
0019 //////////////////////////////////////////////////////////////////////////
0020 //                                                                      //
0021 // TGLBoundingBox                                                       //
0022 //                                                                      //
0023 // Concrete class describing an orientated (free) or axis aligned box   //
0024 // of 8 verticies. Supports methods for setting aligned or orientated   //
0025 // boxes, find volume, axes, extents, centers, face planes etc.         //
0026 // Also tests for overlap testing of planes and other bounding boxes,   //
0027 // with fast sphere approximation.                                      //
0028 //////////////////////////////////////////////////////////////////////////
0029 
0030 // TODO: Create more compact version + axis aligned version, both with lazy
0031 // sphere testing.
0032 class TGLBoundingBox
0033 {
0034 private:
0035    // Fields
0036 
0037    // Box vertices are indexed thus (OpenGL is left handed by default)
0038    //    y
0039    //    |
0040    //    |
0041    //    |________x
0042    //   /  3-------2
0043    //  /  /|      /|
0044    // z  7-------6 |
0045    //    | 0-----|-1
0046    //    |/      |/
0047    //    4-------5
0048    //
0049    // 0123 'far' face
0050    // 4567 'near' face
0051    //
0052    // This could be more compact:
0053    // For orientated box 3 vertices which form plane cutting box
0054    // diagonally (e.g. 0,5,6 or 1,3,6 etc) would fix in space.
0055    // For axis aligned 2 verticies would suffice.
0056    // Rest could be calculated on demand - however speed more important
0057    // than memory considerations
0058    TGLVertex3              fVertex[8];  //! the 8 bounding box vertices
0059    Double_t                fVolume;     //! box volume - cached for speed
0060    Double_t                fDiagonal;   //! max box diagonal - cached for speed
0061    TGLVector3              fAxes[3];    //! box axes in global frame - cached for speed
0062    TGLVector3              fAxesNorm[3];//! normalised box axes in global frame - cached for speed
0063 
0064    // Methods
0065    void     UpdateCache();
0066    Bool_t   ValidIndex(UInt_t index) const { return (index < 8); }
0067    Double_t Min(UInt_t index) const;
0068    Double_t Max(UInt_t index) const;
0069 
0070 public:
0071    TGLBoundingBox();
0072    TGLBoundingBox(const TGLVertex3 vertex[8]);
0073    TGLBoundingBox(const Double_t vertex[8][3]);
0074    TGLBoundingBox(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex);
0075    TGLBoundingBox(const TGLBoundingBox & other);
0076    virtual ~TGLBoundingBox(); // ClassDef introduces virtual fns
0077 
0078    // Set orientated box
0079    TGLBoundingBox & operator =(const TGLBoundingBox & other);
0080    void Set(const TGLVertex3 vertex[8]);
0081    void Set(const Double_t vertex[8][3]);
0082    void Set(const TGLBoundingBox & other);
0083    void SetEmpty();
0084 
0085    // Set axis aligned box
0086    void SetAligned(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex); // axis aligned
0087    void SetAligned(UInt_t nbPnts, const Double_t * pnts); // axis aligned
0088    void MergeAligned(const TGLBoundingBox & other);
0089    void ExpandAligned(const TGLVertex3 & point);
0090 
0091    // Manipulation
0092    void Transform(const TGLMatrix & matrix);
0093    void Scale(Double_t factor);
0094    void Scale(Double_t xFactor, Double_t yFactor, Double_t zFactor);
0095    void Translate(const TGLVector3 & offset);
0096 
0097    // Single vertex accessors
0098    const TGLVertex3 & operator [] (UInt_t index) const;
0099    const TGLVertex3 & Vertex(UInt_t index) const;
0100    Double_t XMin() const { return Min(0); }
0101    Double_t XMax() const { return Max(0); }
0102    Double_t YMin() const { return Min(1); }
0103    Double_t YMax() const { return Max(1); }
0104    Double_t ZMin() const { return Min(2); }
0105    Double_t ZMax() const { return Max(2); }
0106    TGLVertex3 MinAAVertex() const;
0107    TGLVertex3 MaxAAVertex() const;
0108 
0109    // Multiple vertices accessors
0110    const TGLVertex3* Vertices() const;           // All 8 box vertices
0111    Int_t             NumVertices() const { return 8; }
0112 
0113    enum EFace { kFaceLowX, kFaceHighX, kFaceLowY, kFaceHighY, kFaceLowZ, kFaceHighZ, kFaceCount };
0114    const std::vector<UInt_t> & FaceVertices(EFace face) const; // 4 box face vertices
0115 
0116    // Other properties
0117    TGLVertex3   Center() const;
0118    TGLVector3   Extents() const;
0119    const  TGLVector3 & Axis(UInt_t i, Bool_t normalised = kTRUE) const;
0120    Bool_t       IsEmpty()  const;
0121    Double_t     Volume()   const { return fVolume;   }
0122    Double_t     Diagonal() const { return fDiagonal; }
0123    void         PlaneSet(TGLPlaneSet_t & planeSet) const;
0124    TGLPlane     GetNearPlane() const;
0125 
0126    // Overlap testing
0127    Rgl::EOverlap Overlap(const TGLPlane & plane) const;
0128    Rgl::EOverlap Overlap(const TGLBoundingBox & box) const;
0129 
0130    void Draw(Bool_t solid = kFALSE) const;
0131    void Dump() const;
0132 
0133    ClassDef(TGLBoundingBox,0); // a 3D orientated bounding box
0134 };
0135 
0136 //______________________________________________________________________________
0137 inline TGLBoundingBox & TGLBoundingBox::operator =(const TGLBoundingBox & other)
0138 {
0139    // Check for self-assignment
0140    if (this != &other) {
0141       Set(other);
0142    }
0143    return *this;
0144 }
0145 
0146 //______________________________________________________________________________
0147 inline const TGLVertex3 & TGLBoundingBox::operator [] (UInt_t index) const
0148 {
0149    return fVertex[index];
0150 }
0151 
0152 //______________________________________________________________________________
0153 inline const TGLVertex3 & TGLBoundingBox::Vertex(UInt_t index) const
0154 {
0155    return fVertex[index];
0156 }
0157 
0158 //______________________________________________________________________________
0159 inline const TGLVertex3* TGLBoundingBox::Vertices() const
0160 {
0161    return fVertex;
0162 }
0163 
0164 //______________________________________________________________________________
0165 inline TGLVector3 TGLBoundingBox::Extents() const
0166 {
0167    // Return the local axis entents of the box
0168    return TGLVector3(Axis(0,kFALSE).Mag(),
0169                      Axis(1,kFALSE).Mag(),
0170                      Axis(2,kFALSE).Mag());
0171 }
0172 
0173 //______________________________________________________________________________
0174 inline TGLVertex3 TGLBoundingBox::Center() const
0175 {
0176    // Return the center vertex of the box
0177    return TGLVertex3((fVertex[0].X() + fVertex[6].X())/2.0,
0178                      (fVertex[0].Y() + fVertex[6].Y())/2.0,
0179                      (fVertex[0].Z() + fVertex[6].Z())/2.0);
0180 }
0181 
0182 //______________________________________________________________________________
0183 inline const TGLVector3 & TGLBoundingBox::Axis(UInt_t i, Bool_t normalised) const
0184 {
0185    // Return a vector representing axis of index i (0:X, 1:Y, 2:Z).
0186    // Vector can be as-is (edge, magnitude == extent) or normalised (default)
0187    //    y
0188    //    |
0189    //    |
0190    //    |________x
0191    //   /  3-------2
0192    //  /  /|      /|
0193    // z  7-------6 |
0194    //    | 0-----|-1
0195    //    |/      |/
0196    //    4-------5
0197    //
0198 
0199    if (normalised) {
0200       return fAxesNorm[i];
0201    } else {
0202       return fAxes[i];
0203    }
0204 }
0205 
0206 //______________________________________________________________________________
0207 inline Bool_t TGLBoundingBox::IsEmpty() const
0208 {
0209    // Return kTRUE if box has zero diagonal - kFALSE otherwise
0210 
0211    // TODO: Round errors - should have epsilon test
0212    return (Diagonal() == 0.0);
0213 }
0214 
0215 #endif // ROOT_TGLBoundingBox