28 ClassImp(TGLBoundingBox);
 
   33 TGLBoundingBox::TGLBoundingBox()
 
   41 TGLBoundingBox::TGLBoundingBox(
const TGLVertex3 vertex[8])
 
   49 TGLBoundingBox::TGLBoundingBox(
const Double_t vertex[8][3])
 
   57 TGLBoundingBox::TGLBoundingBox(
const TGLVertex3 & lowVertex, 
const TGLVertex3 & highVertex)
 
   59    SetAligned(lowVertex, highVertex);
 
   65 TGLBoundingBox::TGLBoundingBox(
const TGLBoundingBox & other)
 
   73 TGLBoundingBox::~TGLBoundingBox()
 
   81 void TGLBoundingBox::UpdateCache()
 
   96    fAxes[0].Set(fVertex[1] - fVertex[0]);
 
   97    fAxes[1].Set(fVertex[3] - fVertex[0]);
 
   98    fAxes[2].Set(fVertex[4] - fVertex[0]);
 
  102    Bool_t fixZeroMagAxis = kFALSE;
 
  103    Int_t zeroMagAxisInd = -1;
 
  104    for (UInt_t i = 0; i<3; i++) {
 
  105       fAxesNorm[i] = fAxes[i];
 
  106       Double_t mag = fAxesNorm[i].Mag();
 
  110          if (!fixZeroMagAxis && zeroMagAxisInd == -1) {
 
  112             fixZeroMagAxis = kTRUE;
 
  113          } 
else if (fixZeroMagAxis) {
 
  114             fixZeroMagAxis = kFALSE;
 
  121    if (fixZeroMagAxis) {
 
  122       fAxesNorm[zeroMagAxisInd] = Cross(fAxesNorm[(zeroMagAxisInd+1)%3],
 
  123                                         fAxesNorm[(zeroMagAxisInd+2)%3]);
 
  126    TGLVector3 extents = Extents();
 
  127    fVolume   = TMath::Abs(extents.X() * extents.Y() * extents.Z());
 
  128    fDiagonal = extents.Mag();
 
  134 void TGLBoundingBox::Set(
const TGLVertex3 vertex[8])
 
  136    for (UInt_t v = 0; v < 8; v++) {
 
  137       fVertex[v] = vertex[v];
 
  146 void TGLBoundingBox::Set(
const Double_t vertex[8][3])
 
  148    for (UInt_t v = 0; v < 8; v++) {
 
  149       for (UInt_t a = 0; a < 3; a++) {
 
  150          fVertex[v][a] = vertex[v][a];
 
  160 void TGLBoundingBox::Set(
const TGLBoundingBox & other)
 
  162    for (UInt_t v = 0; v < 8; v++) {
 
  163       fVertex[v].Set(other.fVertex[v]);
 
  172 void TGLBoundingBox::SetEmpty()
 
  174    for (UInt_t v = 0; v < 8; v++) {
 
  175       fVertex[v].Fill(0.0);
 
  185 void TGLBoundingBox::SetAligned(
const TGLVertex3 & lowVertex, 
const TGLVertex3 & highVertex)
 
  202    TGLVector3 diff = highVertex - lowVertex;
 
  203    if (diff.X() < 0.0 || diff.Y() < 0.0 || diff.Z() < 0.0) {
 
  204       Error(
"TGLBoundingBox::SetAligned", 
"low/high vertex range error");
 
  206    fVertex[0] = lowVertex;
 
  207    fVertex[1] = lowVertex;  fVertex[1].X() += diff.X();
 
  208    fVertex[2] = lowVertex;  fVertex[2].X() += diff.X(); fVertex[2].Y() += diff.Y();
 
  209    fVertex[3] = lowVertex;  fVertex[3].Y() += diff.Y();
 
  210    fVertex[4] = highVertex; fVertex[4].X() -= diff.X(); fVertex[4].Y() -= diff.Y();
 
  211    fVertex[5] = highVertex; fVertex[5].Y() -= diff.Y();
 
  212    fVertex[6] = highVertex;
 
  213    fVertex[7] = highVertex; fVertex[7].X() -= diff.X();
 
  222 void TGLBoundingBox::SetAligned(UInt_t nbPnts, 
const Double_t * pnts)
 
  224    if (nbPnts < 1 || !pnts) {
 
  230    TGLVertex3 low(pnts[0], pnts[1], pnts[2]);
 
  231    TGLVertex3 high(pnts[0], pnts[1], pnts[2]);
 
  233    for (UInt_t p = 1; p < nbPnts; p++) {
 
  234       for (UInt_t i = 0; i < 3; i++) {
 
  235          if (pnts[3*p + i] < low[i]) {
 
  236             low[i] = pnts[3*p + i] ;
 
  238          if (pnts[3*p + i] > high[i]) {
 
  239             high[i] = pnts[3*p + i] ;
 
  244    SetAligned(low, high);
 
  251 void TGLBoundingBox::MergeAligned(
const TGLBoundingBox & other)
 
  253    if (other.IsEmpty()) 
return;
 
  260       TGLVertex3 low (other.MinAAVertex());
 
  261       TGLVertex3 high(other.MaxAAVertex());
 
  263       low .Minimum(MinAAVertex());
 
  264       high.Maximum(MaxAAVertex());
 
  265       SetAligned(low, high);
 
  273 void TGLBoundingBox::ExpandAligned(
const TGLVertex3 & point)
 
  275    TGLVertex3 low (MinAAVertex());
 
  276    TGLVertex3 high(MaxAAVertex());
 
  281    SetAligned(low, high);
 
  287 void TGLBoundingBox::Scale(Double_t factor)
 
  289    Scale(factor, factor, factor);
 
  297 void TGLBoundingBox::Scale(Double_t xFactor, Double_t yFactor, Double_t zFactor)
 
  301    const TGLVector3 xOffset = Axis(0, kFALSE)*(xFactor - 1.0) / 2.0;
 
  302    const TGLVector3 yOffset = Axis(1, kFALSE)*(yFactor - 1.0) / 2.0;
 
  303    const TGLVector3 zOffset = Axis(2, kFALSE)*(zFactor - 1.0) / 2.0;
 
  316    fVertex[0] += -xOffset - yOffset - zOffset;
 
  317    fVertex[1] +=  xOffset - yOffset - zOffset;
 
  318    fVertex[2] +=  xOffset + yOffset - zOffset;
 
  319    fVertex[3] += -xOffset + yOffset - zOffset;
 
  321    fVertex[4] += -xOffset - yOffset + zOffset;
 
  322    fVertex[5] +=  xOffset - yOffset + zOffset;
 
  323    fVertex[6] +=  xOffset + yOffset + zOffset;
 
  324    fVertex[7] += -xOffset + yOffset + zOffset;
 
  333 void TGLBoundingBox::Translate(
const TGLVector3 & offset)
 
  335    for (UInt_t v = 0; v < 8; v++) {
 
  336       fVertex[v] = fVertex[v] + offset;
 
  345 void TGLBoundingBox::Transform(
const TGLMatrix & matrix)
 
  347    for (UInt_t v = 0; v < 8; v++) {
 
  348       matrix.TransformVertex(fVertex[v]);
 
  369 const std::vector<UInt_t> & TGLBoundingBox::FaceVertices(EFace face)
 const 
  371    static Bool_t init = kFALSE;
 
  372    static std::vector<UInt_t> faceIndexes[kFaceCount];
 
  375       faceIndexes[kFaceLowX].push_back(7);
 
  376       faceIndexes[kFaceLowX].push_back(4);
 
  377       faceIndexes[kFaceLowX].push_back(0);
 
  378       faceIndexes[kFaceLowX].push_back(3);
 
  380       faceIndexes[kFaceHighX].push_back(2);
 
  381       faceIndexes[kFaceHighX].push_back(1);
 
  382       faceIndexes[kFaceHighX].push_back(5);
 
  383       faceIndexes[kFaceHighX].push_back(6);
 
  385       faceIndexes[kFaceLowY].push_back(5);
 
  386       faceIndexes[kFaceLowY].push_back(1);
 
  387       faceIndexes[kFaceLowY].push_back(0);
 
  388       faceIndexes[kFaceLowY].push_back(4);
 
  390       faceIndexes[kFaceHighY].push_back(2);
 
  391       faceIndexes[kFaceHighY].push_back(6);
 
  392       faceIndexes[kFaceHighY].push_back(7);
 
  393       faceIndexes[kFaceHighY].push_back(3);
 
  395       faceIndexes[kFaceLowZ].push_back(3);
 
  396       faceIndexes[kFaceLowZ].push_back(0);
 
  397       faceIndexes[kFaceLowZ].push_back(1);
 
  398       faceIndexes[kFaceLowZ].push_back(2);
 
  400       faceIndexes[kFaceHighZ].push_back(6);
 
  401       faceIndexes[kFaceHighZ].push_back(5);
 
  402       faceIndexes[kFaceHighZ].push_back(4);
 
  403       faceIndexes[kFaceHighZ].push_back(7);
 
  406    return faceIndexes[face];
 
  413 void TGLBoundingBox::PlaneSet(TGLPlaneSet_t & planeSet)
 const 
  415    assert(planeSet.empty());
 
  429    planeSet.push_back(TGLPlane( fAxesNorm[2], fVertex[4])); 
 
  430    planeSet.push_back(TGLPlane(-fAxesNorm[2], fVertex[0])); 
 
  431    planeSet.push_back(TGLPlane(-fAxesNorm[0], fVertex[0])); 
 
  432    planeSet.push_back(TGLPlane( fAxesNorm[0], fVertex[1])); 
 
  433    planeSet.push_back(TGLPlane(-fAxesNorm[1], fVertex[0])); 
 
  434    planeSet.push_back(TGLPlane( fAxesNorm[1], fVertex[3])); 
 
  440 TGLPlane TGLBoundingBox::GetNearPlane()
 const 
  442    return TGLPlane(fAxesNorm[2], fVertex[4]);
 
  448 Rgl::EOverlap TGLBoundingBox::Overlap(
const TGLPlane & plane)
 const 
  454    if (plane.DistanceTo(Center()) + (Extents().Mag()/2.0) < 0.0) {
 
  459    Int_t verticesInsidePlane = 8;
 
  460    for (UInt_t v = 0; v < 8; v++) {
 
  461       if (plane.DistanceTo(fVertex[v]) < 0.0) {
 
  462          verticesInsidePlane--;
 
  466    if ( verticesInsidePlane == 0 ) {
 
  468    } 
else if ( verticesInsidePlane == 8 ) {
 
  478 Rgl::EOverlap TGLBoundingBox::Overlap(
const TGLBoundingBox & other)
 const 
  483    const TGLBoundingBox & a = *
this;
 
  484    const TGLBoundingBox & b = other;
 
  486    TGLVector3 aHL = a.Extents() / 2.0; 
 
  487    TGLVector3 bHL = b.Extents() / 2.0; 
 
  493    TGLVector3 parentT = b.Center() - a.Center();
 
  500    Double_t aSphereRadius = aHL[0] < aHL[1] ? aHL[0] : aHL[1];
 
  501    if (aHL[2] < aSphereRadius) {
 
  502       aSphereRadius = aHL[2];
 
  505    Double_t bSphereRadius = bHL.Mag();
 
  509    if (bSphereRadius + parentT.Mag() < aSphereRadius) {
 
  516    TGLVector3 aT(Dot(parentT, a.Axis(0)), Dot(parentT, a.Axis(1)), Dot(parentT, a.Axis(2)));
 
  522    for (i=0 ; i<3 ; i++) {
 
  523       for (k=0; k<3; k++) {
 
  524          roaT[i][k] = Dot(a.Axis(i), b.Axis(k));
 
  526          if (fabs(roaT[i][k]) < 1e-14) {
 
  531       Double_t norm = sqrt(roaT[i][0]*roaT[i][0] + roaT[i][1]*roaT[i][1] + roaT[i][2]*roaT[i][2]);
 
  532       roaT[i][0] /= norm; roaT[i][1] /= norm; roaT[i][2] /= norm;
 
  540    for (i=0; i<3; i++) {
 
  542       rb = bHL[0]*fabs(roaT[i][0]) + bHL[1]*fabs(roaT[i][1]) + bHL[2]*fabs(roaT[i][2]);
 
  546       else if (ra < t + rb)
 
  551    for (k=0; k<3; k++) {
 
  552       ra = aHL[0]*fabs(roaT[0][k]) + aHL[1]*fabs(roaT[1][k]) + aHL[2]*fabs(roaT[2][k]);
 
  554       t = fabs(aT[0]*roaT[0][k] + aT[1]*roaT[1][k] + aT[2]*roaT[2][k]);
 
  557       else if (ra < t + rb)
 
  564    ra = aHL[1]*fabs(roaT[2][0]) + aHL[2]*fabs(roaT[1][0]);
 
  565    rb = bHL[1]*fabs(roaT[0][2]) + bHL[2]*fabs(roaT[0][1]);
 
  566    t = fabs(aT[2]*roaT[1][0] - aT[1]*roaT[2][0]);
 
  569    else if (ra < t + rb)
 
  573    ra = aHL[1]*fabs(roaT[2][1]) + aHL[2]*fabs(roaT[1][1]);
 
  574    rb = bHL[0]*fabs(roaT[0][2]) + bHL[2]*fabs(roaT[0][0]);
 
  575    t = fabs(aT[2]*roaT[1][1] - aT[1]*roaT[2][1]);
 
  578    else if (ra < t + rb)
 
  582    ra = aHL[1]*fabs(roaT[2][2]) + aHL[2]*fabs(roaT[1][2]);
 
  583    rb = bHL[0]*fabs(roaT[0][1]) + bHL[1]*fabs(roaT[0][0]);
 
  584    t = fabs(aT[2]*roaT[1][2] - aT[1]*roaT[2][2]);
 
  587    else if (ra < t + rb)
 
  591    ra = aHL[0]*fabs(roaT[2][0]) + aHL[2]*fabs(roaT[0][0]);
 
  592    rb = bHL[1]*fabs(roaT[1][2]) + bHL[2]*fabs(roaT[1][1]);
 
  593    t = fabs(aT[0]*roaT[2][0] - aT[2]*roaT[0][0]);
 
  596    else if (ra < t + rb)
 
  600    ra = aHL[0]*fabs(roaT[2][1]) + aHL[2]*fabs(roaT[0][1]);
 
  601    rb = bHL[0]*fabs(roaT[1][2]) + bHL[2]*fabs(roaT[1][0]);
 
  602    t = fabs(aT[0]*roaT[2][1] - aT[2]*roaT[0][1]);
 
  605    else if (ra < t + rb)
 
  609    ra = aHL[0]*fabs(roaT[2][2]) + aHL[2]*fabs(roaT[0][2]);
 
  610    rb = bHL[0]*fabs(roaT[1][1]) + bHL[1]*fabs(roaT[1][0]);
 
  611    t = fabs(aT[0]*roaT[2][2] - aT[2]*roaT[0][2]);
 
  614    else if (ra < t + rb)
 
  618    ra = aHL[0]*fabs(roaT[1][0]) + aHL[1]*fabs(roaT[0][0]);
 
  619    rb = bHL[1]*fabs(roaT[2][2]) + bHL[2]*fabs(roaT[2][1]);
 
  620    t = fabs(aT[1]*roaT[0][0] - aT[0]*roaT[1][0]);
 
  623    else if (ra < t + rb)
 
  627    ra = aHL[0]*fabs(roaT[1][1]) + aHL[1]*fabs(roaT[0][1]);
 
  628    rb = bHL[0]*fabs(roaT[2][2]) + bHL[2]*fabs(roaT[2][0]);
 
  629    t = fabs(aT[1]*roaT[0][1] - aT[0]*roaT[1][1]);
 
  632    else if (ra < t + rb)
 
  636    ra = aHL[0]*fabs(roaT[1][2]) + aHL[1]*fabs(roaT[0][2]);
 
  637    rb = bHL[0]*fabs(roaT[2][1]) + bHL[1]*fabs(roaT[2][0]);
 
  638    t = fabs(aT[1]*roaT[0][2] - aT[0]*roaT[1][2]);
 
  641    else if (ra < t + rb)
 
  652 void TGLBoundingBox::Draw(Bool_t solid)
 const 
  655       glBegin(GL_LINE_LOOP);
 
  656       glVertex3dv(fVertex[0].CArr());
 
  657       glVertex3dv(fVertex[1].CArr());
 
  658       glVertex3dv(fVertex[2].CArr());
 
  659       glVertex3dv(fVertex[3].CArr());
 
  660       glVertex3dv(fVertex[7].CArr());
 
  661       glVertex3dv(fVertex[6].CArr());
 
  662       glVertex3dv(fVertex[5].CArr());
 
  663       glVertex3dv(fVertex[4].CArr());
 
  666       glVertex3dv(fVertex[1].CArr());
 
  667       glVertex3dv(fVertex[5].CArr());
 
  668       glVertex3dv(fVertex[2].CArr());
 
  669       glVertex3dv(fVertex[6].CArr());
 
  670       glVertex3dv(fVertex[0].CArr());
 
  671       glVertex3dv(fVertex[3].CArr());
 
  672       glVertex3dv(fVertex[4].CArr());
 
  673       glVertex3dv(fVertex[7].CArr());
 
  689       glNormal3d ( fAxesNorm[2].X(),  fAxesNorm[2].Y(),  fAxesNorm[2].Z());
 
  690       glVertex3dv(fVertex[4].CArr());
 
  691       glVertex3dv(fVertex[7].CArr());
 
  692       glVertex3dv(fVertex[6].CArr());
 
  693       glVertex3dv(fVertex[5].CArr());
 
  695       glNormal3d (-fAxesNorm[2].X(), -fAxesNorm[2].Y(), -fAxesNorm[2].Z());
 
  696       glVertex3dv(fVertex[0].CArr());
 
  697       glVertex3dv(fVertex[1].CArr());
 
  698       glVertex3dv(fVertex[2].CArr());
 
  699       glVertex3dv(fVertex[3].CArr());
 
  701       glNormal3d (-fAxesNorm[0].X(), -fAxesNorm[0].Y(), -fAxesNorm[0].Z());
 
  702       glVertex3dv(fVertex[0].CArr());
 
  703       glVertex3dv(fVertex[3].CArr());
 
  704       glVertex3dv(fVertex[7].CArr());
 
  705       glVertex3dv(fVertex[4].CArr());
 
  707       glNormal3d ( fAxesNorm[0].X(),  fAxesNorm[0].Y(),  fAxesNorm[0].Z());
 
  708       glVertex3dv(fVertex[6].CArr());
 
  709       glVertex3dv(fVertex[2].CArr());
 
  710       glVertex3dv(fVertex[1].CArr());
 
  711       glVertex3dv(fVertex[5].CArr());
 
  713       glNormal3d ( fAxesNorm[1].X(),  fAxesNorm[1].Y(),  fAxesNorm[1].Z());
 
  714       glVertex3dv(fVertex[3].CArr());
 
  715       glVertex3dv(fVertex[2].CArr());
 
  716       glVertex3dv(fVertex[6].CArr());
 
  717       glVertex3dv(fVertex[7].CArr());
 
  719       glNormal3d (-fAxesNorm[1].X(), -fAxesNorm[1].Y(), -fAxesNorm[1].Z());
 
  720       glVertex3dv(fVertex[4].CArr());
 
  721       glVertex3dv(fVertex[5].CArr());
 
  722       glVertex3dv(fVertex[1].CArr());
 
  723       glVertex3dv(fVertex[0].CArr());
 
  733 Double_t TGLBoundingBox::Min(UInt_t index)
 const 
  735    Double_t min = fVertex[0][index];
 
  736    for (UInt_t v = 1; v < 8; v++) {
 
  737       if (fVertex[v][index] < min) {
 
  738          min = fVertex[v][index];
 
  747 Double_t TGLBoundingBox::Max(UInt_t index)
 const 
  749    Double_t max = fVertex[0][index];
 
  750    for (UInt_t v = 1; v < 8; v++) {
 
  751       if (fVertex[v][index] > max) {
 
  752          max = fVertex[v][index];
 
  761 TGLVertex3 TGLBoundingBox::MinAAVertex()
 const 
  763    return TGLVertex3(Min(0), Min(1), Min(2));
 
  769 TGLVertex3 TGLBoundingBox::MaxAAVertex()
 const 
  771    return TGLVertex3(Max(0), Max(1), Max(2));
 
  777 void TGLBoundingBox::Dump()
 const 
  779    for (UInt_t i = 0; i<8; i++) {
 
  780       std::cout << 
"[" << i << 
"] (" << fVertex[i].X() << 
"," << fVertex[i].Y() << 
"," << fVertex[i].Z() << 
")" << std::endl;
 
  782    std::cout << 
"Center:  ";   Center().Dump();
 
  783    std::cout << 
"Extents: ";   Extents().Dump();
 
  784    std::cout << 
"Volume:  " << Volume() << std::endl;