// @(#)root/gl:$Id$
// Author:  Richard Maunder  25/05/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TGLBoundingBox.h"
#include "TGLIncludes.h"
#include "TMathBase.h"

using namespace std;

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGLBoundingBox                                                       //
//                                                                      //
// Concrete class describing an orientated (free) or axis aligned box   //
// of 8 verticies. Supports methods for setting aligned or orientated   //
// boxes, find volume, axes, extents, centers, face planes etc.         //
// Also tests for overlap testing of planes and other bounding boxes,   //
// with fast sphere approximation.                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(TGLBoundingBox)

//______________________________________________________________________________
TGLBoundingBox::TGLBoundingBox()
{
   // Construct an empty bounding box
   SetEmpty();
}

//______________________________________________________________________________
TGLBoundingBox::TGLBoundingBox(const TGLVertex3 vertex[8])
{
   // Construct a bounding box from provided 8 vertices
   Set(vertex);
}

//______________________________________________________________________________
TGLBoundingBox::TGLBoundingBox(const Double_t vertex[8][3])
{
   // Construct a bounding box from provided 8 vertices
   Set(vertex);
}

//______________________________________________________________________________
TGLBoundingBox::TGLBoundingBox(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex)
{
   // Construct an global axis ALIGNED bounding box from provided low/high vertex pair
   SetAligned(lowVertex, highVertex);
}

//______________________________________________________________________________
TGLBoundingBox::TGLBoundingBox(const TGLBoundingBox & other)
{
   // Construct a bounding box as copy of existing one
   Set(other);
}

//______________________________________________________________________________
TGLBoundingBox::~TGLBoundingBox()
{
  // Destroy bounding box
}

//______________________________________________________________________________
void TGLBoundingBox::UpdateCache()
{
   // Update the internally cached volume and axes vectors - these are retained
   // for efficiency - many more reads than modifications

   //    y
   //    |
   //    |
   //    |________x
   //   /  3-------2
   //  /  /|      /|
   // z  7-------6 |
   //    | 0-----|-1
   //    |/      |/
   //    4-------5
   //

   // Do axes first so Extents() is correct
   fAxes[0].Set(fVertex[1] - fVertex[0]);
   fAxes[1].Set(fVertex[3] - fVertex[0]);
   fAxes[2].Set(fVertex[4] - fVertex[0]);

   // Sometimes have zero volume BB due to single zero magnitude
   // axis record and try to fix below
   Bool_t fixZeroMagAxis = kFALSE;
   Int_t zeroMagAxisInd = -1;
   for (UInt_t i = 0; i<3; i++) {
      fAxesNorm[i] = fAxes[i];
      Double_t mag = fAxesNorm[i].Mag();
      if (mag > 0.0) {
         fAxesNorm[i] /= mag;
      } else {
         if (!fixZeroMagAxis && zeroMagAxisInd == -1) {
            zeroMagAxisInd = i;
            fixZeroMagAxis = kTRUE;
         } else if (fixZeroMagAxis) {
            fixZeroMagAxis = kFALSE;
         }
      }
   }

   // Try to cope with a zero volume bounding box where one
   // axis is zero by using cross product of other two
   if (fixZeroMagAxis) {
      fAxesNorm[zeroMagAxisInd] = Cross(fAxesNorm[(zeroMagAxisInd+1)%3],
                                        fAxesNorm[(zeroMagAxisInd+2)%3]);
   }

   TGLVector3 extents = Extents();
   fVolume   = TMath::Abs(extents.X() * extents.Y() * extents.Z());
   fDiagonal = extents.Mag();
}

//______________________________________________________________________________
void TGLBoundingBox::Set(const TGLVertex3 vertex[8])
{
   // Set a bounding box from provided 8 vertices
   for (UInt_t v = 0; v < 8; v++) {
      fVertex[v] = vertex[v];
   }
   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::Set(const Double_t vertex[8][3])
{
   // Set a bounding box from provided 8 vertices
   for (UInt_t v = 0; v < 8; v++) {
      for (UInt_t a = 0; a < 3; a++) {
         fVertex[v][a] = vertex[v][a];
      }
   }
   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::Set(const TGLBoundingBox & other)
{
   // Set a bounding box from vertices of other
   for (UInt_t v = 0; v < 8; v++) {
      fVertex[v].Set(other.fVertex[v]);
   }
   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::SetEmpty()
{
   // Set bounding box empty - all vertices at (0,0,0)
   for (UInt_t v = 0; v < 8; v++) {
      fVertex[v].Fill(0.0);
   }
   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::SetAligned(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex)
{
   // Set ALIGNED box from two low/high vertices. Box axes are aligned with
   // global frame axes that vertices are specified in.

   // lowVertex = vertex[0]
   // highVertex = vertex[6]
   //
   //    y
   //    |
   //    |
   //    |________x
   //   /  3-------2
   //  /  /|      /|
   // z  7-------6 |
   //    | 0-----|-1
   //    |/      |/
   //    4-------5
   //

   TGLVector3 diff = highVertex - lowVertex;
   if (diff.X() < 0.0 || diff.Y() < 0.0 || diff.Z() < 0.0) {
      Error("TGLBoundingBox::SetAligned", "low/high vertex range error");
   }
   fVertex[0] = lowVertex;
   fVertex[1] = lowVertex;  fVertex[1].X() += diff.X();
   fVertex[2] = lowVertex;  fVertex[2].X() += diff.X(); fVertex[2].Y() += diff.Y();
   fVertex[3] = lowVertex;  fVertex[3].Y() += diff.Y();
   fVertex[4] = highVertex; fVertex[4].X() -= diff.X(); fVertex[4].Y() -= diff.Y();
   fVertex[5] = highVertex; fVertex[5].Y() -= diff.Y();
   fVertex[6] = highVertex;
   fVertex[7] = highVertex; fVertex[7].X() -= diff.X();
   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::SetAligned(UInt_t nbPnts, const Double_t * pnts)
{
   // Set ALIGNED box from one or more points. Box axes are aligned with
   // global frame axes that points are specified in.
   if (nbPnts < 1 || !pnts) {
      assert(false);
      return;
   }

   // Single point gives a zero volume BB
   TGLVertex3 low(pnts[0], pnts[1], pnts[2]);
   TGLVertex3 high(pnts[0], pnts[1], pnts[2]);

   for (UInt_t p = 1; p < nbPnts; p++) {
      for (UInt_t i = 0; i < 3; i++) {
         if (pnts[3*p + i] < low[i]) {
            low[i] = pnts[3*p + i] ;
         }
         if (pnts[3*p + i] > high[i]) {
            high[i] = pnts[3*p + i] ;
         }
      }
   }

   SetAligned(low, high);
}

//______________________________________________________________________________
void TGLBoundingBox::MergeAligned(const TGLBoundingBox & other)
{
   // Expand current bbox so that it includes other's bbox.
   // This make the bbox axis-aligned.

   if (other.IsEmpty()) return;
   if (IsEmpty())
   {
      Set(other);
   }
   else
   {
      TGLVertex3 low (other.MinAAVertex());
      TGLVertex3 high(other.MaxAAVertex());

      low .Minimum(MinAAVertex());
      high.Maximum(MaxAAVertex());
      SetAligned(low, high);
   }
}

//______________________________________________________________________________
void TGLBoundingBox::ExpandAligned(const TGLVertex3 & point)
{
   // Expand current bbox so that it includes the point.
   // This make the bbox axis-aligned.

   TGLVertex3 low (MinAAVertex());
   TGLVertex3 high(MaxAAVertex());

   low .Minimum(point);
   high.Maximum(point);

   SetAligned(low, high);
}

//______________________________________________________________________________
void TGLBoundingBox::Scale(Double_t factor)
{
   // Isotropically scale bounding box along it's LOCAL axes, preserving center
   Scale(factor, factor, factor);
   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::Scale(Double_t xFactor, Double_t yFactor, Double_t zFactor)
{
   // Asymetrically scale box along it's LOCAL x,y,z axes, preserving center

   // Get x,y,z edges (non-normalised axis) and scale
   // them by factors
   const TGLVector3 xOffset = Axis(0, kFALSE)*(xFactor - 1.0) / 2.0;
   const TGLVector3 yOffset = Axis(1, kFALSE)*(yFactor - 1.0) / 2.0;
   const TGLVector3 zOffset = Axis(2, kFALSE)*(zFactor - 1.0) / 2.0;

   //    y
   //    |
   //    |
   //    |________x
   //   /  3-------2
   //  /  /|      /|
   // z  7-------6 |
   //    | 0-----|-1
   //    |/      |/
   //    4-------5
   //
   fVertex[0] += -xOffset - yOffset - zOffset;
   fVertex[1] +=  xOffset - yOffset - zOffset;
   fVertex[2] +=  xOffset + yOffset - zOffset;
   fVertex[3] += -xOffset + yOffset - zOffset;

   fVertex[4] += -xOffset - yOffset + zOffset;
   fVertex[5] +=  xOffset - yOffset + zOffset;
   fVertex[6] +=  xOffset + yOffset + zOffset;
   fVertex[7] += -xOffset + yOffset + zOffset;

   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
void TGLBoundingBox::Translate(const TGLVector3 & offset)
{
   // Translate all vertices by offset
   for (UInt_t v = 0; v < 8; v++) {
      fVertex[v] = fVertex[v] + offset;
   }

   // No cache change - volume and axes vectors remain same
}

//______________________________________________________________________________
void TGLBoundingBox::Transform(const TGLMatrix & matrix)
{
   // Transform all vertices with matrix.

   for (UInt_t v = 0; v < 8; v++) {
      matrix.TransformVertex(fVertex[v]);
   }

   // Could change cached volume/axes
   UpdateCache();
}

//______________________________________________________________________________
const std::vector<UInt_t> & TGLBoundingBox::FaceVertices(EFace face) const
{
   //return a vector of face vertices
   //    y
   //    |
   //    |
   //    |________x
   //   /  3-------2
   //  /  /|      /|
   // z  7-------6 |
   //    | 0-----|-1
   //    |/      |/
   //    4-------5
   //
   static Bool_t init = kFALSE;
   static std::vector<UInt_t> faceIndexes[kFaceCount];
   if (!init) {
      // Low X - 7403
      faceIndexes[kFaceLowX].push_back(7);
      faceIndexes[kFaceLowX].push_back(4);
      faceIndexes[kFaceLowX].push_back(0);
      faceIndexes[kFaceLowX].push_back(3);
      // High X - 2156
      faceIndexes[kFaceHighX].push_back(2);
      faceIndexes[kFaceHighX].push_back(1);
      faceIndexes[kFaceHighX].push_back(5);
      faceIndexes[kFaceHighX].push_back(6);
      // Low Y - 5104
      faceIndexes[kFaceLowY].push_back(5);
      faceIndexes[kFaceLowY].push_back(1);
      faceIndexes[kFaceLowY].push_back(0);
      faceIndexes[kFaceLowY].push_back(4);
      // High Y - 2673
      faceIndexes[kFaceHighY].push_back(2);
      faceIndexes[kFaceHighY].push_back(6);
      faceIndexes[kFaceHighY].push_back(7);
      faceIndexes[kFaceHighY].push_back(3);
      // Low Z - 3012
      faceIndexes[kFaceLowZ].push_back(3);
      faceIndexes[kFaceLowZ].push_back(0);
      faceIndexes[kFaceLowZ].push_back(1);
      faceIndexes[kFaceLowZ].push_back(2);
      // High Z - 6547
      faceIndexes[kFaceHighZ].push_back(6);
      faceIndexes[kFaceHighZ].push_back(5);
      faceIndexes[kFaceHighZ].push_back(4);
      faceIndexes[kFaceHighZ].push_back(7);
      init= kTRUE;
   }
   return faceIndexes[face];
}

//______________________________________________________________________________
void TGLBoundingBox::PlaneSet(TGLPlaneSet_t & planeSet) const
{
   // Fill out supplied plane set vector with TGLPlane objects
   // representing six faces of box
   assert(planeSet.empty());

   //    y
   //    |
   //    |
   //    |________x
   //   /  3-------2
   //  /  /|      /|
   // z  7-------6 |
   //    | 0-----|-1
   //    |/      |/
   //    4-------5
   //
   // Construct plane set using axis + vertices
   planeSet.push_back(TGLPlane( fAxesNorm[2], fVertex[4])); // Near
   planeSet.push_back(TGLPlane(-fAxesNorm[2], fVertex[0])); // Far
   planeSet.push_back(TGLPlane(-fAxesNorm[0], fVertex[0])); // Left
   planeSet.push_back(TGLPlane( fAxesNorm[0], fVertex[1])); // Right
   planeSet.push_back(TGLPlane(-fAxesNorm[1], fVertex[0])); // Bottom
   planeSet.push_back(TGLPlane( fAxesNorm[1], fVertex[3])); // Top
}

//______________________________________________________________________________
TGLPlane TGLBoundingBox::GetNearPlane() const
{
   // Return the near-plane.

   return TGLPlane(fAxesNorm[2], fVertex[4]);
}

//______________________________________________________________________________
Rgl::EOverlap TGLBoundingBox::Overlap(const TGLPlane & plane) const
{
   // Find overlap (Inside, Outside, Partial) of plane c.f. bounding box.

   using namespace Rgl;

   // First : cheap square approxiamtion test. If distance of our
   // center to plane > our half extent length we are outside plane
   if (plane.DistanceTo(Center()) + (Extents().Mag()/2.0) < 0.0) {
      return kOutside;
   }

   // Second : test all 8 box vertices against plane
   Int_t verticesInsidePlane = 8;
   for (UInt_t v = 0; v < 8; v++) {
      if (plane.DistanceTo(fVertex[v]) < 0.0) {
         verticesInsidePlane--;
      }
   }

   if ( verticesInsidePlane == 0 ) {
      return kOutside;
   } else if ( verticesInsidePlane == 8 ) {
      return kInside;
   } else {
      return kPartial;
   }
}

//______________________________________________________________________________
Rgl::EOverlap TGLBoundingBox::Overlap(const TGLBoundingBox & other) const
{
   // Find overlap (Inside, Outside, Partial) of other bounding box c.f. us.

   using namespace Rgl;

   // Simplify code with refs
   const TGLBoundingBox & a = *this;
   const TGLBoundingBox & b = other;

   TGLVector3 aHL = a.Extents() / 2.0; // Half length extents
   TGLVector3 bHL = b.Extents() / 2.0; // Half length extents

   // Following tests are greatly simplified
   // if we convert into our local frame

   // Find translation in parent frame
   TGLVector3 parentT = b.Center() - a.Center();

   // First: Do a simple & cheap sphere approximation containment test.
   // In many uses b will be completely contained by a and very much smaller
   // these cases short circuited here

   // We need the inner sphere for the container (box a) - radius = shortest box half length
   Double_t aSphereRadius = aHL[0] < aHL[1] ? aHL[0] : aHL[1];
   if (aHL[2] < aSphereRadius) {
      aSphereRadius = aHL[2];
   }
   // and the outer sphere for containee (box b) - radius = box diagonal
   Double_t bSphereRadius = bHL.Mag();

   // If b sphere radius + translation mag is smaller than b sphere radius
   // b is complete contained by a
   if (bSphereRadius + parentT.Mag() < aSphereRadius) {
      return kInside;
   }

   // Second: Perform more expensive 15 seperating axes test

   // Find translation in A's frame
   TGLVector3 aT(Dot(parentT, a.Axis(0)), Dot(parentT, a.Axis(1)), Dot(parentT, a.Axis(2)));

   // Find B's basis with respect to A's local frame
   // Get rotation matrix
   Double_t   roaT[3][3];
   UInt_t     i, k;
   for (i=0 ; i<3 ; i++) {
      for (k=0; k<3; k++) {
         roaT[i][k] = Dot(a.Axis(i), b.Axis(k));
         // Force very small components to zero to avoid rounding errors
         if (fabs(roaT[i][k]) < 1e-14) {
            roaT[i][k] = 0.0;
         }
      }
      // Normalise columns to avoid rounding errors
      Double_t norm = sqrt(roaT[i][0]*roaT[i][0] + roaT[i][1]*roaT[i][1] + roaT[i][2]*roaT[i][2]);
      roaT[i][0] /= norm; roaT[i][1] /= norm; roaT[i][2] /= norm;
   }

   // Perform separating axis test for all 15 potential
   // axes. If no separating axes found, the two boxes overlap.
   Double_t ra, rb, t;

   // A's 3 basis vectors
   for (i=0; i<3; i++) {
      ra = aHL[i];
      rb = bHL[0]*fabs(roaT[i][0]) + bHL[1]*fabs(roaT[i][1]) + bHL[2]*fabs(roaT[i][2]);
      t = fabs(aT[i]);
      if (t > ra + rb)
         return kOutside;
      else if (ra < t + rb)
         return kPartial;
   }

   // B's 3 basis vectors
   for (k=0; k<3; k++) {
      ra = aHL[0]*fabs(roaT[0][k]) + aHL[1]*fabs(roaT[1][k]) + aHL[2]*fabs(roaT[2][k]);
      rb = bHL[k];
      t = fabs(aT[0]*roaT[0][k] + aT[1]*roaT[1][k] + aT[2]*roaT[2][k]);
      if (t > ra + rb)
         return kOutside;
      else if (ra < t + rb)
         return kPartial;
   }

   // Now the 9 cross products

   // A0 x B0
   ra = aHL[1]*fabs(roaT[2][0]) + aHL[2]*fabs(roaT[1][0]);
   rb = bHL[1]*fabs(roaT[0][2]) + bHL[2]*fabs(roaT[0][1]);
   t = fabs(aT[2]*roaT[1][0] - aT[1]*roaT[2][0]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A0 x B1
   ra = aHL[1]*fabs(roaT[2][1]) + aHL[2]*fabs(roaT[1][1]);
   rb = bHL[0]*fabs(roaT[0][2]) + bHL[2]*fabs(roaT[0][0]);
   t = fabs(aT[2]*roaT[1][1] - aT[1]*roaT[2][1]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A0 x B2
   ra = aHL[1]*fabs(roaT[2][2]) + aHL[2]*fabs(roaT[1][2]);
   rb = bHL[0]*fabs(roaT[0][1]) + bHL[1]*fabs(roaT[0][0]);
   t = fabs(aT[2]*roaT[1][2] - aT[1]*roaT[2][2]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A1 x B0
   ra = aHL[0]*fabs(roaT[2][0]) + aHL[2]*fabs(roaT[0][0]);
   rb = bHL[1]*fabs(roaT[1][2]) + bHL[2]*fabs(roaT[1][1]);
   t = fabs(aT[0]*roaT[2][0] - aT[2]*roaT[0][0]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A1 x B1
   ra = aHL[0]*fabs(roaT[2][1]) + aHL[2]*fabs(roaT[0][1]);
   rb = bHL[0]*fabs(roaT[1][2]) + bHL[2]*fabs(roaT[1][0]);
   t = fabs(aT[0]*roaT[2][1] - aT[2]*roaT[0][1]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A1 x B2
   ra = aHL[0]*fabs(roaT[2][2]) + aHL[2]*fabs(roaT[0][2]);
   rb = bHL[0]*fabs(roaT[1][1]) + bHL[1]*fabs(roaT[1][0]);
   t = fabs(aT[0]*roaT[2][2] - aT[2]*roaT[0][2]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A2 x B0
   ra = aHL[0]*fabs(roaT[1][0]) + aHL[1]*fabs(roaT[0][0]);
   rb = bHL[1]*fabs(roaT[2][2]) + bHL[2]*fabs(roaT[2][1]);
   t = fabs(aT[1]*roaT[0][0] - aT[0]*roaT[1][0]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A2 x B1
   ra = aHL[0]*fabs(roaT[1][1]) + aHL[1]*fabs(roaT[0][1]);
   rb = bHL[0]*fabs(roaT[2][2]) + bHL[2]*fabs(roaT[2][0]);
   t = fabs(aT[1]*roaT[0][1] - aT[0]*roaT[1][1]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // A2 x B2
   ra = aHL[0]*fabs(roaT[1][2]) + aHL[1]*fabs(roaT[0][2]);
   rb = bHL[0]*fabs(roaT[2][1]) + bHL[1]*fabs(roaT[2][0]);
   t = fabs(aT[1]*roaT[0][2] - aT[0]*roaT[1][2]);
   if (t > ra + rb)
      return kOutside;
   else if (ra < t + rb)
      return kPartial;

   // No separating axis - b is inside a
   return kInside;
}

//______________________________________________________________________________
void TGLBoundingBox::Draw(Bool_t solid) const
{
   // Draw the bounding box as either wireframe (default) of solid
   // using current GL color.

   if (!solid) {
      glBegin(GL_LINE_LOOP);
      glVertex3dv(fVertex[0].CArr());
      glVertex3dv(fVertex[1].CArr());
      glVertex3dv(fVertex[2].CArr());
      glVertex3dv(fVertex[3].CArr());
      glVertex3dv(fVertex[7].CArr());
      glVertex3dv(fVertex[6].CArr());
      glVertex3dv(fVertex[5].CArr());
      glVertex3dv(fVertex[4].CArr());
      glEnd();
      glBegin(GL_LINES);
      glVertex3dv(fVertex[1].CArr());
      glVertex3dv(fVertex[5].CArr());
      glVertex3dv(fVertex[2].CArr());
      glVertex3dv(fVertex[6].CArr());
      glVertex3dv(fVertex[0].CArr());
      glVertex3dv(fVertex[3].CArr());
      glVertex3dv(fVertex[4].CArr());
      glVertex3dv(fVertex[7].CArr());
      glEnd();
   } else {
   //    y
   //    |
   //    |
   //    |________x
   //   /  3-------2
   //  /  /|      /|
   // z  7-------6 |
   //    | 0-----|-1
   //    |/      |/
   //    4-------5
      // Clockwise winding
      glBegin(GL_QUADS);
      // Near
      glNormal3d ( fAxesNorm[2].X(),  fAxesNorm[2].Y(),  fAxesNorm[2].Z());
      glVertex3dv(fVertex[4].CArr());
      glVertex3dv(fVertex[7].CArr());
      glVertex3dv(fVertex[6].CArr());
      glVertex3dv(fVertex[5].CArr());
      // Far
      glNormal3d (-fAxesNorm[2].X(), -fAxesNorm[2].Y(), -fAxesNorm[2].Z());
      glVertex3dv(fVertex[0].CArr());
      glVertex3dv(fVertex[1].CArr());
      glVertex3dv(fVertex[2].CArr());
      glVertex3dv(fVertex[3].CArr());
      // Left
      glNormal3d (-fAxesNorm[0].X(), -fAxesNorm[0].Y(), -fAxesNorm[0].Z());
      glVertex3dv(fVertex[0].CArr());
      glVertex3dv(fVertex[3].CArr());
      glVertex3dv(fVertex[7].CArr());
      glVertex3dv(fVertex[4].CArr());
      // Right
      glNormal3d ( fAxesNorm[0].X(),  fAxesNorm[0].Y(),  fAxesNorm[0].Z());
      glVertex3dv(fVertex[6].CArr());
      glVertex3dv(fVertex[2].CArr());
      glVertex3dv(fVertex[1].CArr());
      glVertex3dv(fVertex[5].CArr());
      // Top
      glNormal3d ( fAxesNorm[1].X(),  fAxesNorm[1].Y(),  fAxesNorm[1].Z());
      glVertex3dv(fVertex[3].CArr());
      glVertex3dv(fVertex[2].CArr());
      glVertex3dv(fVertex[6].CArr());
      glVertex3dv(fVertex[7].CArr());
      // Bottom
      glNormal3d (-fAxesNorm[1].X(), -fAxesNorm[1].Y(), -fAxesNorm[1].Z());
      glVertex3dv(fVertex[4].CArr());
      glVertex3dv(fVertex[5].CArr());
      glVertex3dv(fVertex[1].CArr());
      glVertex3dv(fVertex[0].CArr());

      glEnd();
   }

}

//______________________________________________________________________________
Double_t TGLBoundingBox::Min(UInt_t index) const
{
   // Find minimum vertex value for axis of index X(0), Y(1), Z(2)
   Double_t min = fVertex[0][index];
   for (UInt_t v = 1; v < 8; v++) {
      if (fVertex[v][index] < min) {
         min = fVertex[v][index];
      }
   }
   return min;
}

//______________________________________________________________________________
Double_t TGLBoundingBox::Max(UInt_t index) const
{
   // Find maximum vertex value for axis of index X(0), Y(1), Z(2)
   Double_t max = fVertex[0][index];
   for (UInt_t v = 1; v < 8; v++) {
      if (fVertex[v][index] > max) {
         max = fVertex[v][index];
      }
   }
   return max;
}

//______________________________________________________________________________
TGLVertex3 TGLBoundingBox::MinAAVertex() const
{
   // Find minimum vertex values.

   return TGLVertex3(Min(0), Min(1), Min(2));
}

//______________________________________________________________________________
TGLVertex3 TGLBoundingBox::MaxAAVertex() const
{
   // Find maximum vertex values.

   return TGLVertex3(Max(0), Max(1), Max(2));
}

//______________________________________________________________________________
void TGLBoundingBox::Dump() const
{
   // Output to std::cout the vertices, center and volume of box
   for (UInt_t i = 0; i<8; i++) {
      std::cout << "[" << i << "] (" << fVertex[i].X() << "," << fVertex[i].Y() << "," << fVertex[i].Z() << ")" << std::endl;
   }
   std::cout << "Center:  ";   Center().Dump();
   std::cout << "Extents: ";   Extents().Dump();
   std::cout << "Volume:  " << Volume() << std::endl;
}

 TGLBoundingBox.cxx:1
 TGLBoundingBox.cxx:2
 TGLBoundingBox.cxx:3
 TGLBoundingBox.cxx:4
 TGLBoundingBox.cxx:5
 TGLBoundingBox.cxx:6
 TGLBoundingBox.cxx:7
 TGLBoundingBox.cxx:8
 TGLBoundingBox.cxx:9
 TGLBoundingBox.cxx:10
 TGLBoundingBox.cxx:11
 TGLBoundingBox.cxx:12
 TGLBoundingBox.cxx:13
 TGLBoundingBox.cxx:14
 TGLBoundingBox.cxx:15
 TGLBoundingBox.cxx:16
 TGLBoundingBox.cxx:17
 TGLBoundingBox.cxx:18
 TGLBoundingBox.cxx:19
 TGLBoundingBox.cxx:20
 TGLBoundingBox.cxx:21
 TGLBoundingBox.cxx:22
 TGLBoundingBox.cxx:23
 TGLBoundingBox.cxx:24
 TGLBoundingBox.cxx:25
 TGLBoundingBox.cxx:26
 TGLBoundingBox.cxx:27
 TGLBoundingBox.cxx:28
 TGLBoundingBox.cxx:29
 TGLBoundingBox.cxx:30
 TGLBoundingBox.cxx:31
 TGLBoundingBox.cxx:32
 TGLBoundingBox.cxx:33
 TGLBoundingBox.cxx:34
 TGLBoundingBox.cxx:35
 TGLBoundingBox.cxx:36
 TGLBoundingBox.cxx:37
 TGLBoundingBox.cxx:38
 TGLBoundingBox.cxx:39
 TGLBoundingBox.cxx:40
 TGLBoundingBox.cxx:41
 TGLBoundingBox.cxx:42
 TGLBoundingBox.cxx:43
 TGLBoundingBox.cxx:44
 TGLBoundingBox.cxx:45
 TGLBoundingBox.cxx:46
 TGLBoundingBox.cxx:47
 TGLBoundingBox.cxx:48
 TGLBoundingBox.cxx:49
 TGLBoundingBox.cxx:50
 TGLBoundingBox.cxx:51
 TGLBoundingBox.cxx:52
 TGLBoundingBox.cxx:53
 TGLBoundingBox.cxx:54
 TGLBoundingBox.cxx:55
 TGLBoundingBox.cxx:56
 TGLBoundingBox.cxx:57
 TGLBoundingBox.cxx:58
 TGLBoundingBox.cxx:59
 TGLBoundingBox.cxx:60
 TGLBoundingBox.cxx:61
 TGLBoundingBox.cxx:62
 TGLBoundingBox.cxx:63
 TGLBoundingBox.cxx:64
 TGLBoundingBox.cxx:65
 TGLBoundingBox.cxx:66
 TGLBoundingBox.cxx:67
 TGLBoundingBox.cxx:68
 TGLBoundingBox.cxx:69
 TGLBoundingBox.cxx:70
 TGLBoundingBox.cxx:71
 TGLBoundingBox.cxx:72
 TGLBoundingBox.cxx:73
 TGLBoundingBox.cxx:74
 TGLBoundingBox.cxx:75
 TGLBoundingBox.cxx:76
 TGLBoundingBox.cxx:77
 TGLBoundingBox.cxx:78
 TGLBoundingBox.cxx:79
 TGLBoundingBox.cxx:80
 TGLBoundingBox.cxx:81
 TGLBoundingBox.cxx:82
 TGLBoundingBox.cxx:83
 TGLBoundingBox.cxx:84
 TGLBoundingBox.cxx:85
 TGLBoundingBox.cxx:86
 TGLBoundingBox.cxx:87
 TGLBoundingBox.cxx:88
 TGLBoundingBox.cxx:89
 TGLBoundingBox.cxx:90
 TGLBoundingBox.cxx:91
 TGLBoundingBox.cxx:92
 TGLBoundingBox.cxx:93
 TGLBoundingBox.cxx:94
 TGLBoundingBox.cxx:95
 TGLBoundingBox.cxx:96
 TGLBoundingBox.cxx:97
 TGLBoundingBox.cxx:98
 TGLBoundingBox.cxx:99
 TGLBoundingBox.cxx:100
 TGLBoundingBox.cxx:101
 TGLBoundingBox.cxx:102
 TGLBoundingBox.cxx:103
 TGLBoundingBox.cxx:104
 TGLBoundingBox.cxx:105
 TGLBoundingBox.cxx:106
 TGLBoundingBox.cxx:107
 TGLBoundingBox.cxx:108
 TGLBoundingBox.cxx:109
 TGLBoundingBox.cxx:110
 TGLBoundingBox.cxx:111
 TGLBoundingBox.cxx:112
 TGLBoundingBox.cxx:113
 TGLBoundingBox.cxx:114
 TGLBoundingBox.cxx:115
 TGLBoundingBox.cxx:116
 TGLBoundingBox.cxx:117
 TGLBoundingBox.cxx:118
 TGLBoundingBox.cxx:119
 TGLBoundingBox.cxx:120
 TGLBoundingBox.cxx:121
 TGLBoundingBox.cxx:122
 TGLBoundingBox.cxx:123
 TGLBoundingBox.cxx:124
 TGLBoundingBox.cxx:125
 TGLBoundingBox.cxx:126
 TGLBoundingBox.cxx:127
 TGLBoundingBox.cxx:128
 TGLBoundingBox.cxx:129
 TGLBoundingBox.cxx:130
 TGLBoundingBox.cxx:131
 TGLBoundingBox.cxx:132
 TGLBoundingBox.cxx:133
 TGLBoundingBox.cxx:134
 TGLBoundingBox.cxx:135
 TGLBoundingBox.cxx:136
 TGLBoundingBox.cxx:137
 TGLBoundingBox.cxx:138
 TGLBoundingBox.cxx:139
 TGLBoundingBox.cxx:140
 TGLBoundingBox.cxx:141
 TGLBoundingBox.cxx:142
 TGLBoundingBox.cxx:143
 TGLBoundingBox.cxx:144
 TGLBoundingBox.cxx:145
 TGLBoundingBox.cxx:146
 TGLBoundingBox.cxx:147
 TGLBoundingBox.cxx:148
 TGLBoundingBox.cxx:149
 TGLBoundingBox.cxx:150
 TGLBoundingBox.cxx:151
 TGLBoundingBox.cxx:152
 TGLBoundingBox.cxx:153
 TGLBoundingBox.cxx:154
 TGLBoundingBox.cxx:155
 TGLBoundingBox.cxx:156
 TGLBoundingBox.cxx:157
 TGLBoundingBox.cxx:158
 TGLBoundingBox.cxx:159
 TGLBoundingBox.cxx:160
 TGLBoundingBox.cxx:161
 TGLBoundingBox.cxx:162
 TGLBoundingBox.cxx:163
 TGLBoundingBox.cxx:164
 TGLBoundingBox.cxx:165
 TGLBoundingBox.cxx:166
 TGLBoundingBox.cxx:167
 TGLBoundingBox.cxx:168
 TGLBoundingBox.cxx:169
 TGLBoundingBox.cxx:170
 TGLBoundingBox.cxx:171
 TGLBoundingBox.cxx:172
 TGLBoundingBox.cxx:173
 TGLBoundingBox.cxx:174
 TGLBoundingBox.cxx:175
 TGLBoundingBox.cxx:176
 TGLBoundingBox.cxx:177
 TGLBoundingBox.cxx:178
 TGLBoundingBox.cxx:179
 TGLBoundingBox.cxx:180
 TGLBoundingBox.cxx:181
 TGLBoundingBox.cxx:182
 TGLBoundingBox.cxx:183
 TGLBoundingBox.cxx:184
 TGLBoundingBox.cxx:185
 TGLBoundingBox.cxx:186
 TGLBoundingBox.cxx:187
 TGLBoundingBox.cxx:188
 TGLBoundingBox.cxx:189
 TGLBoundingBox.cxx:190
 TGLBoundingBox.cxx:191
 TGLBoundingBox.cxx:192
 TGLBoundingBox.cxx:193
 TGLBoundingBox.cxx:194
 TGLBoundingBox.cxx:195
 TGLBoundingBox.cxx:196
 TGLBoundingBox.cxx:197
 TGLBoundingBox.cxx:198
 TGLBoundingBox.cxx:199
 TGLBoundingBox.cxx:200
 TGLBoundingBox.cxx:201
 TGLBoundingBox.cxx:202
 TGLBoundingBox.cxx:203
 TGLBoundingBox.cxx:204
 TGLBoundingBox.cxx:205
 TGLBoundingBox.cxx:206
 TGLBoundingBox.cxx:207
 TGLBoundingBox.cxx:208
 TGLBoundingBox.cxx:209
 TGLBoundingBox.cxx:210
 TGLBoundingBox.cxx:211
 TGLBoundingBox.cxx:212
 TGLBoundingBox.cxx:213
 TGLBoundingBox.cxx:214
 TGLBoundingBox.cxx:215
 TGLBoundingBox.cxx:216
 TGLBoundingBox.cxx:217
 TGLBoundingBox.cxx:218
 TGLBoundingBox.cxx:219
 TGLBoundingBox.cxx:220
 TGLBoundingBox.cxx:221
 TGLBoundingBox.cxx:222
 TGLBoundingBox.cxx:223
 TGLBoundingBox.cxx:224
 TGLBoundingBox.cxx:225
 TGLBoundingBox.cxx:226
 TGLBoundingBox.cxx:227
 TGLBoundingBox.cxx:228
 TGLBoundingBox.cxx:229
 TGLBoundingBox.cxx:230
 TGLBoundingBox.cxx:231
 TGLBoundingBox.cxx:232
 TGLBoundingBox.cxx:233
 TGLBoundingBox.cxx:234
 TGLBoundingBox.cxx:235
 TGLBoundingBox.cxx:236
 TGLBoundingBox.cxx:237
 TGLBoundingBox.cxx:238
 TGLBoundingBox.cxx:239
 TGLBoundingBox.cxx:240
 TGLBoundingBox.cxx:241
 TGLBoundingBox.cxx:242
 TGLBoundingBox.cxx:243
 TGLBoundingBox.cxx:244
 TGLBoundingBox.cxx:245
 TGLBoundingBox.cxx:246
 TGLBoundingBox.cxx:247
 TGLBoundingBox.cxx:248
 TGLBoundingBox.cxx:249
 TGLBoundingBox.cxx:250
 TGLBoundingBox.cxx:251
 TGLBoundingBox.cxx:252
 TGLBoundingBox.cxx:253
 TGLBoundingBox.cxx:254
 TGLBoundingBox.cxx:255
 TGLBoundingBox.cxx:256
 TGLBoundingBox.cxx:257
 TGLBoundingBox.cxx:258
 TGLBoundingBox.cxx:259
 TGLBoundingBox.cxx:260
 TGLBoundingBox.cxx:261
 TGLBoundingBox.cxx:262
 TGLBoundingBox.cxx:263
 TGLBoundingBox.cxx:264
 TGLBoundingBox.cxx:265
 TGLBoundingBox.cxx:266
 TGLBoundingBox.cxx:267
 TGLBoundingBox.cxx:268
 TGLBoundingBox.cxx:269
 TGLBoundingBox.cxx:270
 TGLBoundingBox.cxx:271
 TGLBoundingBox.cxx:272
 TGLBoundingBox.cxx:273
 TGLBoundingBox.cxx:274
 TGLBoundingBox.cxx:275
 TGLBoundingBox.cxx:276
 TGLBoundingBox.cxx:277
 TGLBoundingBox.cxx:278
 TGLBoundingBox.cxx:279
 TGLBoundingBox.cxx:280
 TGLBoundingBox.cxx:281
 TGLBoundingBox.cxx:282
 TGLBoundingBox.cxx:283
 TGLBoundingBox.cxx:284
 TGLBoundingBox.cxx:285
 TGLBoundingBox.cxx:286
 TGLBoundingBox.cxx:287
 TGLBoundingBox.cxx:288
 TGLBoundingBox.cxx:289
 TGLBoundingBox.cxx:290
 TGLBoundingBox.cxx:291
 TGLBoundingBox.cxx:292
 TGLBoundingBox.cxx:293
 TGLBoundingBox.cxx:294
 TGLBoundingBox.cxx:295
 TGLBoundingBox.cxx:296
 TGLBoundingBox.cxx:297
 TGLBoundingBox.cxx:298
 TGLBoundingBox.cxx:299
 TGLBoundingBox.cxx:300
 TGLBoundingBox.cxx:301
 TGLBoundingBox.cxx:302
 TGLBoundingBox.cxx:303
 TGLBoundingBox.cxx:304
 TGLBoundingBox.cxx:305
 TGLBoundingBox.cxx:306
 TGLBoundingBox.cxx:307
 TGLBoundingBox.cxx:308
 TGLBoundingBox.cxx:309
 TGLBoundingBox.cxx:310
 TGLBoundingBox.cxx:311
 TGLBoundingBox.cxx:312
 TGLBoundingBox.cxx:313
 TGLBoundingBox.cxx:314
 TGLBoundingBox.cxx:315
 TGLBoundingBox.cxx:316
 TGLBoundingBox.cxx:317
 TGLBoundingBox.cxx:318
 TGLBoundingBox.cxx:319
 TGLBoundingBox.cxx:320
 TGLBoundingBox.cxx:321
 TGLBoundingBox.cxx:322
 TGLBoundingBox.cxx:323
 TGLBoundingBox.cxx:324
 TGLBoundingBox.cxx:325
 TGLBoundingBox.cxx:326
 TGLBoundingBox.cxx:327
 TGLBoundingBox.cxx:328
 TGLBoundingBox.cxx:329
 TGLBoundingBox.cxx:330
 TGLBoundingBox.cxx:331
 TGLBoundingBox.cxx:332
 TGLBoundingBox.cxx:333
 TGLBoundingBox.cxx:334
 TGLBoundingBox.cxx:335
 TGLBoundingBox.cxx:336
 TGLBoundingBox.cxx:337
 TGLBoundingBox.cxx:338
 TGLBoundingBox.cxx:339
 TGLBoundingBox.cxx:340
 TGLBoundingBox.cxx:341
 TGLBoundingBox.cxx:342
 TGLBoundingBox.cxx:343
 TGLBoundingBox.cxx:344
 TGLBoundingBox.cxx:345
 TGLBoundingBox.cxx:346
 TGLBoundingBox.cxx:347
 TGLBoundingBox.cxx:348
 TGLBoundingBox.cxx:349
 TGLBoundingBox.cxx:350
 TGLBoundingBox.cxx:351
 TGLBoundingBox.cxx:352
 TGLBoundingBox.cxx:353
 TGLBoundingBox.cxx:354
 TGLBoundingBox.cxx:355
 TGLBoundingBox.cxx:356
 TGLBoundingBox.cxx:357
 TGLBoundingBox.cxx:358
 TGLBoundingBox.cxx:359
 TGLBoundingBox.cxx:360
 TGLBoundingBox.cxx:361
 TGLBoundingBox.cxx:362
 TGLBoundingBox.cxx:363
 TGLBoundingBox.cxx:364
 TGLBoundingBox.cxx:365
 TGLBoundingBox.cxx:366
 TGLBoundingBox.cxx:367
 TGLBoundingBox.cxx:368
 TGLBoundingBox.cxx:369
 TGLBoundingBox.cxx:370
 TGLBoundingBox.cxx:371
 TGLBoundingBox.cxx:372
 TGLBoundingBox.cxx:373
 TGLBoundingBox.cxx:374
 TGLBoundingBox.cxx:375
 TGLBoundingBox.cxx:376
 TGLBoundingBox.cxx:377
 TGLBoundingBox.cxx:378
 TGLBoundingBox.cxx:379
 TGLBoundingBox.cxx:380
 TGLBoundingBox.cxx:381
 TGLBoundingBox.cxx:382
 TGLBoundingBox.cxx:383
 TGLBoundingBox.cxx:384
 TGLBoundingBox.cxx:385
 TGLBoundingBox.cxx:386
 TGLBoundingBox.cxx:387
 TGLBoundingBox.cxx:388
 TGLBoundingBox.cxx:389
 TGLBoundingBox.cxx:390
 TGLBoundingBox.cxx:391
 TGLBoundingBox.cxx:392
 TGLBoundingBox.cxx:393
 TGLBoundingBox.cxx:394
 TGLBoundingBox.cxx:395
 TGLBoundingBox.cxx:396
 TGLBoundingBox.cxx:397
 TGLBoundingBox.cxx:398
 TGLBoundingBox.cxx:399
 TGLBoundingBox.cxx:400
 TGLBoundingBox.cxx:401
 TGLBoundingBox.cxx:402
 TGLBoundingBox.cxx:403
 TGLBoundingBox.cxx:404
 TGLBoundingBox.cxx:405
 TGLBoundingBox.cxx:406
 TGLBoundingBox.cxx:407
 TGLBoundingBox.cxx:408
 TGLBoundingBox.cxx:409
 TGLBoundingBox.cxx:410
 TGLBoundingBox.cxx:411
 TGLBoundingBox.cxx:412
 TGLBoundingBox.cxx:413
 TGLBoundingBox.cxx:414
 TGLBoundingBox.cxx:415
 TGLBoundingBox.cxx:416
 TGLBoundingBox.cxx:417
 TGLBoundingBox.cxx:418
 TGLBoundingBox.cxx:419
 TGLBoundingBox.cxx:420
 TGLBoundingBox.cxx:421
 TGLBoundingBox.cxx:422
 TGLBoundingBox.cxx:423
 TGLBoundingBox.cxx:424
 TGLBoundingBox.cxx:425
 TGLBoundingBox.cxx:426
 TGLBoundingBox.cxx:427
 TGLBoundingBox.cxx:428
 TGLBoundingBox.cxx:429
 TGLBoundingBox.cxx:430
 TGLBoundingBox.cxx:431
 TGLBoundingBox.cxx:432
 TGLBoundingBox.cxx:433
 TGLBoundingBox.cxx:434
 TGLBoundingBox.cxx:435
 TGLBoundingBox.cxx:436
 TGLBoundingBox.cxx:437
 TGLBoundingBox.cxx:438
 TGLBoundingBox.cxx:439
 TGLBoundingBox.cxx:440
 TGLBoundingBox.cxx:441
 TGLBoundingBox.cxx:442
 TGLBoundingBox.cxx:443
 TGLBoundingBox.cxx:444
 TGLBoundingBox.cxx:445
 TGLBoundingBox.cxx:446
 TGLBoundingBox.cxx:447
 TGLBoundingBox.cxx:448
 TGLBoundingBox.cxx:449
 TGLBoundingBox.cxx:450
 TGLBoundingBox.cxx:451
 TGLBoundingBox.cxx:452
 TGLBoundingBox.cxx:453
 TGLBoundingBox.cxx:454
 TGLBoundingBox.cxx:455
 TGLBoundingBox.cxx:456
 TGLBoundingBox.cxx:457
 TGLBoundingBox.cxx:458
 TGLBoundingBox.cxx:459
 TGLBoundingBox.cxx:460
 TGLBoundingBox.cxx:461
 TGLBoundingBox.cxx:462
 TGLBoundingBox.cxx:463
 TGLBoundingBox.cxx:464
 TGLBoundingBox.cxx:465
 TGLBoundingBox.cxx:466
 TGLBoundingBox.cxx:467
 TGLBoundingBox.cxx:468
 TGLBoundingBox.cxx:469
 TGLBoundingBox.cxx:470
 TGLBoundingBox.cxx:471
 TGLBoundingBox.cxx:472
 TGLBoundingBox.cxx:473
 TGLBoundingBox.cxx:474
 TGLBoundingBox.cxx:475
 TGLBoundingBox.cxx:476
 TGLBoundingBox.cxx:477
 TGLBoundingBox.cxx:478
 TGLBoundingBox.cxx:479
 TGLBoundingBox.cxx:480
 TGLBoundingBox.cxx:481
 TGLBoundingBox.cxx:482
 TGLBoundingBox.cxx:483
 TGLBoundingBox.cxx:484
 TGLBoundingBox.cxx:485
 TGLBoundingBox.cxx:486
 TGLBoundingBox.cxx:487
 TGLBoundingBox.cxx:488
 TGLBoundingBox.cxx:489
 TGLBoundingBox.cxx:490
 TGLBoundingBox.cxx:491
 TGLBoundingBox.cxx:492
 TGLBoundingBox.cxx:493
 TGLBoundingBox.cxx:494
 TGLBoundingBox.cxx:495
 TGLBoundingBox.cxx:496
 TGLBoundingBox.cxx:497
 TGLBoundingBox.cxx:498
 TGLBoundingBox.cxx:499
 TGLBoundingBox.cxx:500
 TGLBoundingBox.cxx:501
 TGLBoundingBox.cxx:502
 TGLBoundingBox.cxx:503
 TGLBoundingBox.cxx:504
 TGLBoundingBox.cxx:505
 TGLBoundingBox.cxx:506
 TGLBoundingBox.cxx:507
 TGLBoundingBox.cxx:508
 TGLBoundingBox.cxx:509
 TGLBoundingBox.cxx:510
 TGLBoundingBox.cxx:511
 TGLBoundingBox.cxx:512
 TGLBoundingBox.cxx:513
 TGLBoundingBox.cxx:514
 TGLBoundingBox.cxx:515
 TGLBoundingBox.cxx:516
 TGLBoundingBox.cxx:517
 TGLBoundingBox.cxx:518
 TGLBoundingBox.cxx:519
 TGLBoundingBox.cxx:520
 TGLBoundingBox.cxx:521
 TGLBoundingBox.cxx:522
 TGLBoundingBox.cxx:523
 TGLBoundingBox.cxx:524
 TGLBoundingBox.cxx:525
 TGLBoundingBox.cxx:526
 TGLBoundingBox.cxx:527
 TGLBoundingBox.cxx:528
 TGLBoundingBox.cxx:529
 TGLBoundingBox.cxx:530
 TGLBoundingBox.cxx:531
 TGLBoundingBox.cxx:532
 TGLBoundingBox.cxx:533
 TGLBoundingBox.cxx:534
 TGLBoundingBox.cxx:535
 TGLBoundingBox.cxx:536
 TGLBoundingBox.cxx:537
 TGLBoundingBox.cxx:538
 TGLBoundingBox.cxx:539
 TGLBoundingBox.cxx:540
 TGLBoundingBox.cxx:541
 TGLBoundingBox.cxx:542
 TGLBoundingBox.cxx:543
 TGLBoundingBox.cxx:544
 TGLBoundingBox.cxx:545
 TGLBoundingBox.cxx:546
 TGLBoundingBox.cxx:547
 TGLBoundingBox.cxx:548
 TGLBoundingBox.cxx:549
 TGLBoundingBox.cxx:550
 TGLBoundingBox.cxx:551
 TGLBoundingBox.cxx:552
 TGLBoundingBox.cxx:553
 TGLBoundingBox.cxx:554
 TGLBoundingBox.cxx:555
 TGLBoundingBox.cxx:556
 TGLBoundingBox.cxx:557
 TGLBoundingBox.cxx:558
 TGLBoundingBox.cxx:559
 TGLBoundingBox.cxx:560
 TGLBoundingBox.cxx:561
 TGLBoundingBox.cxx:562
 TGLBoundingBox.cxx:563
 TGLBoundingBox.cxx:564
 TGLBoundingBox.cxx:565
 TGLBoundingBox.cxx:566
 TGLBoundingBox.cxx:567
 TGLBoundingBox.cxx:568
 TGLBoundingBox.cxx:569
 TGLBoundingBox.cxx:570
 TGLBoundingBox.cxx:571
 TGLBoundingBox.cxx:572
 TGLBoundingBox.cxx:573
 TGLBoundingBox.cxx:574
 TGLBoundingBox.cxx:575
 TGLBoundingBox.cxx:576
 TGLBoundingBox.cxx:577
 TGLBoundingBox.cxx:578
 TGLBoundingBox.cxx:579
 TGLBoundingBox.cxx:580
 TGLBoundingBox.cxx:581
 TGLBoundingBox.cxx:582
 TGLBoundingBox.cxx:583
 TGLBoundingBox.cxx:584
 TGLBoundingBox.cxx:585
 TGLBoundingBox.cxx:586
 TGLBoundingBox.cxx:587
 TGLBoundingBox.cxx:588
 TGLBoundingBox.cxx:589
 TGLBoundingBox.cxx:590
 TGLBoundingBox.cxx:591
 TGLBoundingBox.cxx:592
 TGLBoundingBox.cxx:593
 TGLBoundingBox.cxx:594
 TGLBoundingBox.cxx:595
 TGLBoundingBox.cxx:596
 TGLBoundingBox.cxx:597
 TGLBoundingBox.cxx:598
 TGLBoundingBox.cxx:599
 TGLBoundingBox.cxx:600
 TGLBoundingBox.cxx:601
 TGLBoundingBox.cxx:602
 TGLBoundingBox.cxx:603
 TGLBoundingBox.cxx:604
 TGLBoundingBox.cxx:605
 TGLBoundingBox.cxx:606
 TGLBoundingBox.cxx:607
 TGLBoundingBox.cxx:608
 TGLBoundingBox.cxx:609
 TGLBoundingBox.cxx:610
 TGLBoundingBox.cxx:611
 TGLBoundingBox.cxx:612
 TGLBoundingBox.cxx:613
 TGLBoundingBox.cxx:614
 TGLBoundingBox.cxx:615
 TGLBoundingBox.cxx:616
 TGLBoundingBox.cxx:617
 TGLBoundingBox.cxx:618
 TGLBoundingBox.cxx:619
 TGLBoundingBox.cxx:620
 TGLBoundingBox.cxx:621
 TGLBoundingBox.cxx:622
 TGLBoundingBox.cxx:623
 TGLBoundingBox.cxx:624
 TGLBoundingBox.cxx:625
 TGLBoundingBox.cxx:626
 TGLBoundingBox.cxx:627
 TGLBoundingBox.cxx:628
 TGLBoundingBox.cxx:629
 TGLBoundingBox.cxx:630
 TGLBoundingBox.cxx:631
 TGLBoundingBox.cxx:632
 TGLBoundingBox.cxx:633
 TGLBoundingBox.cxx:634
 TGLBoundingBox.cxx:635
 TGLBoundingBox.cxx:636
 TGLBoundingBox.cxx:637
 TGLBoundingBox.cxx:638
 TGLBoundingBox.cxx:639
 TGLBoundingBox.cxx:640
 TGLBoundingBox.cxx:641
 TGLBoundingBox.cxx:642
 TGLBoundingBox.cxx:643
 TGLBoundingBox.cxx:644
 TGLBoundingBox.cxx:645
 TGLBoundingBox.cxx:646
 TGLBoundingBox.cxx:647
 TGLBoundingBox.cxx:648
 TGLBoundingBox.cxx:649
 TGLBoundingBox.cxx:650
 TGLBoundingBox.cxx:651
 TGLBoundingBox.cxx:652
 TGLBoundingBox.cxx:653
 TGLBoundingBox.cxx:654
 TGLBoundingBox.cxx:655
 TGLBoundingBox.cxx:656
 TGLBoundingBox.cxx:657
 TGLBoundingBox.cxx:658
 TGLBoundingBox.cxx:659
 TGLBoundingBox.cxx:660
 TGLBoundingBox.cxx:661
 TGLBoundingBox.cxx:662
 TGLBoundingBox.cxx:663
 TGLBoundingBox.cxx:664
 TGLBoundingBox.cxx:665
 TGLBoundingBox.cxx:666
 TGLBoundingBox.cxx:667
 TGLBoundingBox.cxx:668
 TGLBoundingBox.cxx:669
 TGLBoundingBox.cxx:670
 TGLBoundingBox.cxx:671
 TGLBoundingBox.cxx:672
 TGLBoundingBox.cxx:673
 TGLBoundingBox.cxx:674
 TGLBoundingBox.cxx:675
 TGLBoundingBox.cxx:676
 TGLBoundingBox.cxx:677
 TGLBoundingBox.cxx:678
 TGLBoundingBox.cxx:679
 TGLBoundingBox.cxx:680
 TGLBoundingBox.cxx:681
 TGLBoundingBox.cxx:682
 TGLBoundingBox.cxx:683
 TGLBoundingBox.cxx:684
 TGLBoundingBox.cxx:685
 TGLBoundingBox.cxx:686
 TGLBoundingBox.cxx:687
 TGLBoundingBox.cxx:688
 TGLBoundingBox.cxx:689
 TGLBoundingBox.cxx:690
 TGLBoundingBox.cxx:691
 TGLBoundingBox.cxx:692
 TGLBoundingBox.cxx:693
 TGLBoundingBox.cxx:694
 TGLBoundingBox.cxx:695
 TGLBoundingBox.cxx:696
 TGLBoundingBox.cxx:697
 TGLBoundingBox.cxx:698
 TGLBoundingBox.cxx:699
 TGLBoundingBox.cxx:700
 TGLBoundingBox.cxx:701
 TGLBoundingBox.cxx:702
 TGLBoundingBox.cxx:703
 TGLBoundingBox.cxx:704
 TGLBoundingBox.cxx:705
 TGLBoundingBox.cxx:706
 TGLBoundingBox.cxx:707
 TGLBoundingBox.cxx:708
 TGLBoundingBox.cxx:709
 TGLBoundingBox.cxx:710
 TGLBoundingBox.cxx:711
 TGLBoundingBox.cxx:712
 TGLBoundingBox.cxx:713
 TGLBoundingBox.cxx:714
 TGLBoundingBox.cxx:715
 TGLBoundingBox.cxx:716
 TGLBoundingBox.cxx:717
 TGLBoundingBox.cxx:718
 TGLBoundingBox.cxx:719
 TGLBoundingBox.cxx:720
 TGLBoundingBox.cxx:721
 TGLBoundingBox.cxx:722
 TGLBoundingBox.cxx:723
 TGLBoundingBox.cxx:724
 TGLBoundingBox.cxx:725
 TGLBoundingBox.cxx:726
 TGLBoundingBox.cxx:727
 TGLBoundingBox.cxx:728
 TGLBoundingBox.cxx:729
 TGLBoundingBox.cxx:730
 TGLBoundingBox.cxx:731
 TGLBoundingBox.cxx:732
 TGLBoundingBox.cxx:733
 TGLBoundingBox.cxx:734
 TGLBoundingBox.cxx:735
 TGLBoundingBox.cxx:736
 TGLBoundingBox.cxx:737
 TGLBoundingBox.cxx:738
 TGLBoundingBox.cxx:739
 TGLBoundingBox.cxx:740
 TGLBoundingBox.cxx:741
 TGLBoundingBox.cxx:742
 TGLBoundingBox.cxx:743
 TGLBoundingBox.cxx:744
 TGLBoundingBox.cxx:745
 TGLBoundingBox.cxx:746
 TGLBoundingBox.cxx:747
 TGLBoundingBox.cxx:748
 TGLBoundingBox.cxx:749
 TGLBoundingBox.cxx:750
 TGLBoundingBox.cxx:751
 TGLBoundingBox.cxx:752
 TGLBoundingBox.cxx:753
 TGLBoundingBox.cxx:754
 TGLBoundingBox.cxx:755
 TGLBoundingBox.cxx:756
 TGLBoundingBox.cxx:757
 TGLBoundingBox.cxx:758
 TGLBoundingBox.cxx:759
 TGLBoundingBox.cxx:760
 TGLBoundingBox.cxx:761
 TGLBoundingBox.cxx:762
 TGLBoundingBox.cxx:763
 TGLBoundingBox.cxx:764
 TGLBoundingBox.cxx:765
 TGLBoundingBox.cxx:766
 TGLBoundingBox.cxx:767
 TGLBoundingBox.cxx:768
 TGLBoundingBox.cxx:769
 TGLBoundingBox.cxx:770