31 ClassImp(TEveCalo3DGL);
36 TEveCalo3DGL::TEveCalo3DGL() :
45 Bool_t TEveCalo3DGL::SetModel(TObject* obj,
const Option_t* )
47 fM = SetModelDynCast<TEveCalo3D>(obj);
54 void TEveCalo3DGL::SetBBox()
57 SetAxisAlignedBBox(((TEveCalo3D*)fExternalObj)->AssertBBox());
65 Bool_t TEveCalo3DGL::ShouldDLCache(
const TGLRnrCtx& rnrCtx)
const
67 if (rnrCtx.Highlight() || rnrCtx.Selection())
return kFALSE;
68 return TGLObject::ShouldDLCache(rnrCtx);
74 inline void TEveCalo3DGL::CrossProduct(
const Float_t a[3],
const Float_t b[3],
75 const Float_t c[3], Float_t out[3])
const
77 const Float_t v1[3] = { a[0] - c[0], a[1] - c[1], a[2] - c[2] };
78 const Float_t v2[3] = { b[0] - c[0], b[1] - c[1], b[2] - c[2] };
80 out[0] = v1[1] * v2[2] - v1[2] * v2[1];
81 out[1] = v1[2] * v2[0] - v1[0] * v2[2];
82 out[2] = v1[0] * v2[1] - v1[1] * v2[0];
88 void TEveCalo3DGL::RenderGridEndCap()
const
90 using namespace TMath;
92 Float_t rB = fM->GetBarrelRadius();
93 Double_t zEF = fM->GetForwardEndCapPos();
94 Double_t zEB = fM->GetBackwardEndCapPos();
96 Float_t etaMin = fM->GetEtaMin();
97 Float_t etaMax = fM->GetEtaMax();
98 Float_t transF = fM->GetTransitionEtaForward();
99 Float_t transB = fM->GetTransitionEtaBackward();
100 Float_t phiMin = fM->GetPhiMin();
101 Float_t phiMax = fM->GetPhiMax();
103 TAxis *ax = fM->GetData()->GetEtaBins();
104 Int_t nx = ax->GetNbins();
105 TAxis *ay = fM->GetData()->GetPhiBins();
106 Int_t ny = ay->GetNbins();
109 Float_t r, z, theta, phiU, phiL, eta;
112 for (Int_t i=0; i<=nx; ++i)
114 eta = ax->GetBinUpEdge(i);
115 if (eta >= transF && (eta > etaMin && eta < etaMax))
117 theta = TEveCaloData::EtaToTheta(eta);
118 r = Abs(zEF*Tan(theta));
119 z = Sign(zEF, ax->GetBinLowEdge(i));
120 for (Int_t j=1; j<=ny; ++j)
122 phiL = ay->GetBinLowEdge(j);
123 phiU = ay->GetBinUpEdge(j);
124 if (TEveUtil::IsU1IntervalContainedByMinMax(phiMin, phiMax, phiL, phiU))
126 glVertex3f(r*Cos(phiL), r*Sin(phiL), z);
127 glVertex3f(r*Cos(phiU), r*Sin(phiU), z);
130 }
else if (eta <= transB && (eta > etaMin && eta < etaMax)) {
131 theta = TEveCaloData::EtaToTheta(eta);
132 r = Abs(zEB*Tan(theta));
133 z = Sign(zEB, ax->GetBinLowEdge(i));
134 for (Int_t j=1; j<=ny; ++j)
136 phiL = ay->GetBinLowEdge(j);
137 phiU = ay->GetBinUpEdge(j);
138 if (TEveUtil::IsU1IntervalContainedByMinMax(phiMin, phiMax, phiL, phiU))
140 glVertex3f(r*Cos(phiL), r*Sin(phiL), z);
141 glVertex3f(r*Cos(phiU), r*Sin(phiU), z);
151 r1 = zEF*Tan(TEveCaloData::EtaToTheta(etaMax));
155 r2 = zEF*Tan(TEveCaloData::EtaToTheta(etaMin));
157 for (Int_t j=1; j<=ny; ++j)
159 phiL = ay->GetBinLowEdge(j);
160 phiU = ay->GetBinUpEdge(j);
161 if (TEveUtil::IsU1IntervalContainedByMinMax(phiMin, phiMax, phiL, phiU))
163 glVertex3f( r1*Cos(phiU), r1*Sin(phiU), zEF);
164 glVertex3f( r2*Cos(phiU), r2*Sin(phiU), zEF);
165 glVertex3f( r1*Cos(phiL), r1*Sin(phiL), zEF);
166 glVertex3f( r2*Cos(phiL), r2*Sin(phiL), zEF);
174 r1 = zEB*Tan(TEveCaloData::EtaToTheta(etaMin));
178 r2 = zEB*Tan(TEveCaloData::EtaToTheta(etaMax));
182 for (Int_t j=1; j<=ny; ++j)
184 phiL = ay->GetBinLowEdge(j);
185 phiU = ay->GetBinUpEdge(j);
186 if (TEveUtil::IsU1IntervalContainedByMinMax(phiMin, phiMax, phiL, phiU))
188 glVertex3f(r1*Cos(phiU), r1*Sin(phiU), zEB);
189 glVertex3f(r2*Cos(phiU), r2*Sin(phiU), zEB);
190 glVertex3f(r1*Cos(phiL), r1*Sin(phiL), zEB);
191 glVertex3f(r2*Cos(phiL), r2*Sin(phiL), zEB);
200 void TEveCalo3DGL::RenderGridBarrel()
const
202 using namespace TMath;
204 Float_t etaMin = fM->GetEtaMin();
205 Float_t etaMax = fM->GetEtaMax();
206 Float_t transF = fM->GetTransitionEtaForward();
207 Float_t transB = fM->GetTransitionEtaBackward();
208 Float_t phiMin = fM->GetPhiMin();
209 Float_t phiMax = fM->GetPhiMax();
211 Float_t rB = fM->GetBarrelRadius();
212 TAxis *ax = fM->GetData()->GetEtaBins();
213 Int_t nx = ax->GetNbins();
214 TAxis *ay = fM->GetData()->GetPhiBins();
215 Int_t ny = ay->GetNbins();
217 Float_t z, theta, phiL, phiU, eta, x, y;
220 for(Int_t i=0; i<=nx; i++)
222 eta = ax->GetBinUpEdge(i);
223 if (eta<=transF && eta>=transB && (etaMin < eta && eta < etaMax))
225 theta = TEveCaloData::EtaToTheta(eta);
227 for (Int_t j=1; j<=ny; j++)
229 phiU = ay->GetBinUpEdge(j);
230 phiL = ay->GetBinLowEdge(j);
231 if (TEveUtil::IsU1IntervalContainedByMinMax(phiMin, phiMax, phiL, phiU))
233 glVertex3f(rB*Cos(phiL), rB*Sin(phiL), z);
234 glVertex3f(rB*Cos(phiU), rB*Sin(phiU), z);
244 zB = rB/Tan(TEveCaloData::EtaToTheta(etaMin));
246 zB = fM->GetBackwardEndCapPos();
250 zF = rB/Tan(TEveCaloData::EtaToTheta(etaMax));
252 zF = fM->GetForwardEndCapPos();
254 for (Int_t j=1; j<=ny; j++)
256 phiU = ay->GetBinUpEdge(j);
257 phiL = ay->GetBinLowEdge(j);
258 if (TEveUtil::IsU1IntervalContainedByMinMax(phiMin, phiMax, phiL, phiU))
262 glVertex3f(x, y, zB);
263 glVertex3f(x, y, zF);
266 glVertex3f(x, y, zB);
267 glVertex3f(x, y, zF);
275 void TEveCalo3DGL::RenderGrid(TGLRnrCtx & rnrCtx)
const
277 if (rnrCtx.Highlight() || rnrCtx.Selection() || rnrCtx.IsDrawPassOutlineLine())
return;
279 Bool_t transparent_p = fM->fFrameTransparency > 0;
283 glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
285 glDepthMask(GL_FALSE);
287 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
289 TGLUtil::ColorTransparency(fM->fFrameColor, fM->fFrameTransparency);
292 TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
294 TGLUtil::LineWidth(fM->GetFrameWidth());
297 Float_t etaMin = fM->GetEtaMin();
298 Float_t etaMax = fM->GetEtaMax();
300 Float_t transF = fM->GetTransitionEtaForward();
301 Float_t transB = fM->GetTransitionEtaBackward();
302 if (fM->GetRnrBarrelFrame() && (etaMin < transF && etaMax > transB))
307 if (fM->GetRnrEndCapFrame() && (etaMax > transF || etaMin < transB))
335 void TEveCalo3DGL::RenderBox(
const Float_t pnts[8])
const
337 const Float_t *p = pnts;
342 CrossProduct(p+3, p+9, p, cross);
351 CrossProduct(p+21, p+15, p+12, cross);
360 CrossProduct(p+12, p+3, p, cross);
369 CrossProduct(p+6, p+21, p+9, cross);
378 CrossProduct(p+21, p, p+9, cross);
387 CrossProduct(p+15, p+6, p+3, cross);
399 void TEveCalo3DGL::RenderBarrelCell(
const TEveCaloData::CellGeom_t &cellData, Float_t towerH, Float_t& offset )
const
401 using namespace TMath;
403 Float_t r1 = fM->GetBarrelRadius() + offset;
404 Float_t r2 = r1 + towerH*Sin(cellData.ThetaMin());
405 Float_t z1In, z1Out, z2In, z2Out;
407 z1In = r1/Tan(cellData.ThetaMax());
408 z1Out = r2/Tan(cellData.ThetaMax());
409 z2In = r1/Tan(cellData.ThetaMin());
410 z2Out = r2/Tan(cellData.ThetaMin());
412 Float_t cos1 = Cos(cellData.PhiMin());
413 Float_t sin1 = Sin(cellData.PhiMin());
414 Float_t cos2 = Cos(cellData.PhiMax());
415 Float_t sin2 = Sin(cellData.PhiMax());
462 offset += towerH*Sin(cellData.ThetaMin());
469 void TEveCalo3DGL::RenderEndCapCell(
const TEveCaloData::CellGeom_t &cellData, Float_t towerH, Float_t& offset )
const
471 using namespace TMath;
472 Float_t z1, r1In, r1Out, z2, r2In, r2Out;
474 z1 = (cellData.EtaMin()<0) ? fM->fEndCapPosB : fM->fEndCapPosF;
475 z2 = z1 + TMath::Sign(towerH, cellData.EtaMin());
477 r1In = z1*Tan(cellData.ThetaMin());
478 r2In = z2*Tan(cellData.ThetaMin());
479 r1Out = z1*Tan(cellData.ThetaMax());
480 r2Out = z2*Tan(cellData.ThetaMax());
482 Float_t cos2 = Cos(cellData.PhiMin());
483 Float_t sin2 = Sin(cellData.PhiMin());
484 Float_t cos1 = Cos(cellData.PhiMax());
485 Float_t sin1 = Sin(cellData.PhiMax());
511 pnts[0] = r1Out*cos1;
512 pnts[1] = r1Out*sin1;
516 pnts[0] = r1Out*cos2;
517 pnts[1] = r1Out*sin2;
521 pnts[0] = r2Out*cos2;
522 pnts[1] = r2Out*sin2;
526 pnts[0] = r2Out*cos1;
527 pnts[1] = r2Out*sin1;
533 offset += towerH * Cos(cellData.ThetaMin());
535 offset -= towerH * Cos(cellData.ThetaMin());
542 void TEveCalo3DGL::DirectDraw(TGLRnrCtx &rnrCtx)
const
544 if ( fM->GetValueIsColor()) fM->AssertPalette();
547 if (fM->fCellIdCacheOK == kFALSE)
548 fM->BuildCellIdCache();
550 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
551 glEnable(GL_LIGHTING);
552 glEnable(GL_NORMALIZE);
554 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
556 TEveCaloData::CellData_t cellData;
559 Int_t prevTower = -1;
563 if (rnrCtx.SecSelection()) glPushName(0);
565 fOffset.assign(fM->fCellList.size(), 0);
566 for (TEveCaloData::vCellId_i i = fM->fCellList.begin(); i != fM->fCellList.end(); ++i)
568 fM->fData->GetCellData((*i), cellData);
570 if (tower != prevTower)
575 fOffset[cellID] = offset;
576 fM->SetupColorHeight(cellData.Value(fM->fPlotEt), (*i).fSlice, towerH);
578 if (rnrCtx.SecSelection()) glLoadName(cellID);
580 if ((cellData.Eta() > 0 && cellData.Eta() < fM->GetTransitionEtaForward()) ||
581 (cellData.Eta() < 0 && cellData.Eta() > fM->GetTransitionEtaBackward()))
583 RenderBarrelCell(cellData, towerH, offset);
587 RenderEndCapCell(cellData, towerH, offset);
592 if (rnrCtx.SecSelection()) glPopName();
602 void TEveCalo3DGL::DrawHighlight(TGLRnrCtx & rnrCtx,
const TGLPhysicalShape* , Int_t )
const
604 if (fM->fData->GetCellsSelected().empty() && fM->fData->GetCellsHighlighted().empty())
609 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
610 glDisable(GL_LIGHTING);
611 glDisable(GL_CULL_FACE);
612 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
614 TGLUtil::LineWidth(2);
615 TGLUtil::LockColor();
617 if (!fM->fData->GetCellsHighlighted().empty())
619 glColor4ubv(rnrCtx.ColorSet().Selection(3).CArr());
620 DrawSelectedCells(fM->fData->GetCellsHighlighted());
622 if (!fM->fData->GetCellsSelected().empty())
625 glGetFloatv(GL_DEPTH_RANGE,dr);
626 glColor4ubv(rnrCtx.ColorSet().Selection(1).CArr());
627 glDepthRange(dr[0], 0.8*dr[1]);
628 DrawSelectedCells(fM->fData->GetCellsSelected());
629 glDepthRange(dr[0], dr[1]);
632 TGLUtil::UnlockColor();
638 void TEveCalo3DGL::DrawSelectedCells(TEveCaloData::vCellId_t cells)
const
640 TEveCaloData::CellData_t cellData;
643 for (TEveCaloData::vCellId_i i = cells.begin(); i != cells.end(); i++)
645 fM->fData->GetCellData(*i, cellData);
646 fM->SetupColorHeight(cellData.Value(fM->fPlotEt), (*i).fSlice, towerH);
650 for (Int_t j = 0; j < (Int_t) fM->fCellList.size(); ++j)
652 if (fM->fCellList[j].fTower == i->fTower && fM->fCellList[j].fSlice == i->fSlice )
659 if (fM->CellInEtaPhiRng(cellData))
661 if (cellData.Eta() < fM->GetTransitionEtaForward() && cellData.Eta() > fM->GetTransitionEtaBackward())
662 RenderBarrelCell(cellData, towerH, offset);
664 RenderEndCapCell(cellData, towerH, offset);
673 void TEveCalo3DGL::ProcessSelection(TGLRnrCtx& , TGLSelectRecord& rec)
675 TEveCaloData::vCellId_t sel;
678 sel.push_back(fM->fCellList[rec.GetItem(1)]);
680 fM->fData->ProcessSelection(sel, rec);