30 ClassImp(TGLCameraOverlay);
34 TGLCameraOverlay::TGLCameraOverlay(Bool_t showOrtho, Bool_t showPersp) :
37 fShowOrthographic(showOrtho),
38 fShowPerspective(showPersp),
40 fOrthographicMode(kAxis),
41 fPerspectiveMode(kPlaneIntersect),
46 fUseAxisColors(kFALSE),
49 fUseExternalRefPlane(kFALSE)
53 fFrustum[0] = fFrustum[1] = fFrustum[2] = fFrustum[3] = 0;
56 fAxis->SetNdivisions(710);
57 fAxis->SetLabelSize(0.018);
58 fAxis->SetLabelOffset(0.01);
59 fAxis->SetAxisColor(kGray+1);
60 fAxis->SetLabelColor(kGray+1);
62 fAxisPainter =
new TGLAxisPainter();
63 fAxisPainter->SetFontMode(TGLFont::kBitmap);
64 fAxisPainter->SetUseAxisColors(kFALSE);
70 TGLCameraOverlay::~TGLCameraOverlay()
79 TAttAxis* TGLCameraOverlay::GetAttAxis()
81 return dynamic_cast<TAttAxis*
>(fAxis);
87 void TGLCameraOverlay::SetFrustum(TGLCamera& cam)
89 TGLVector3 absRef(1., 1., 1.);
90 Float_t l = -cam.FrustumPlane(TGLCamera::kLeft).D() * Dot(cam.GetCamBase().GetBaseVec(2), absRef);
91 Float_t r = cam.FrustumPlane(TGLCamera::kRight).D() * Dot(cam.GetCamBase().GetBaseVec(2), absRef);
92 Float_t t = cam.FrustumPlane(TGLCamera::kTop).D();
93 Float_t b = -cam.FrustumPlane(TGLCamera::kBottom).D();
104 void TGLCameraOverlay::RenderPlaneIntersect(TGLRnrCtx& rnrCtx)
106 TGLCamera &cam = rnrCtx.RefCamera();
108 const TGLMatrix& mx = cam.GetCamBase() * cam.GetCamTrans();
109 TGLVertex3 d = mx.GetTranslation();
110 TGLVertex3 p = d + mx.GetBaseVec(1);
113 const TGLPlane rp = (fUseExternalRefPlane) ? fExternalRefPlane :
114 TGLPlane(cam.GetCamBase().GetBaseVec(3), TGLVertex3());
116 std::pair<Bool_t, TGLVertex3> intersection;
117 intersection = Intersection(rp, line, kTRUE);
119 if (intersection.first)
121 TGLVertex3 v = intersection.second;
123 glMatrixMode(GL_PROJECTION);
127 glMatrixMode(GL_MODELVIEW);
131 TGLRect &vp = rnrCtx.GetCamera()->RefViewport();
133 Int_t fs = TMath::Nint(TMath::Sqrt(vp.Width()*vp.Width() + vp.Height()*vp.Height())*0.02);
134 rnrCtx.RegisterFontNoScale(fs,
"arial", TGLFont::kPixmap, font);
135 const char* txt = Form(
"(%f, %f, %f)", v[0], v[1], v[2]);
136 TGLUtil::Color(rnrCtx.ColorSet().Markup());
137 font.Render(txt, 0.98, 0.98, 0, TGLFont::kRight, TGLFont::kBottom);
140 TGLUtil::Color(kRed);
144 glVertex2f(0 +w*ce, 0);
147 glVertex2f(0 -w*ce, 0);
150 Float_t h = w*vp.Width()/vp.Height();
151 glVertex2f(0, 0 +h*ce);
154 glVertex2f(0, 0 -h*ce);
159 glMatrixMode(GL_PROJECTION);
161 glMatrixMode(GL_MODELVIEW);
168 void TGLCameraOverlay::RenderAxis(TGLRnrCtx& rnrCtx, Bool_t grid)
170 fAxisPainter->SetAttAxis(fAxis);
171 fAxisPainter->SetUseAxisColors(fUseAxisColors);
173 Color_t lineColor = fUseAxisColors ? fAxis->GetAxisColor() : rnrCtx.ColorSet().Markup().GetColorIndex();
176 GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp);
177 Float_t rl = 0.5 *((vp[2]-vp[0]) + (vp[3]-vp[1]));
178 Int_t fsizePx = (Int_t)(fAxis->GetLabelSize()*rl);
180 Float_t tlY = 0.015*rl/(vp[2]-vp[0]);
181 Float_t tlX = 0.015*rl/(vp[3]-vp[1]);
184 TGLVector3 xdir = rnrCtx.RefCamera().GetCamBase().GetBaseVec(2); xdir.Normalise();
185 if (fFrustum[2] > fFrustum[0] )
196 TGLVector3 ydir = rnrCtx.RefCamera().GetCamBase().GetBaseVec(3); ydir.Normalise();
197 TGLVector3 vy1 = ydir * fFrustum[1];
198 TGLVector3 vy2 = ydir * fFrustum[3];
200 TGLVector3 vx1 = xdir * minX;
201 TGLVector3 vx2 = xdir * maxX;
203 Double_t rngY = fFrustum[3] - fFrustum[1];
204 Double_t rngX = maxX - minX;
205 Double_t off = TMath::Sqrt((rngX*rngX)+(rngY*rngY)) * 0.03;
206 Double_t minY = fFrustum[1] + off;
207 Double_t maxY = fFrustum[3] - off;
214 Int_t secSteps = fAxis->GetNdivisions() % 100;
215 GLushort stipple = 0x5555;
219 fAxisPainter->SetLabelPixelFontSize(fsizePx);
220 fAxis->SetTickLength(tlX);
221 fAxisPainter->RefDir() = xdir;
222 fAxis->SetLimits(minX, maxX);
223 fAxisPainter->RefTMOff(0) = ydir*rngY;
227 glTranslated(vy1.X(), vy1.Y(), vy1.Z());
228 fAxisPainter->SetLabelAlign(TGLFont::kCenterH, TGLFont::kTop);
229 fAxisPainter->PaintAxis(rnrCtx, fAxis);
234 glTranslated(vy2.X(), vy2.Y(), vy2.Z());
235 fAxisPainter->SetLabelAlign(TGLFont::kCenterH, TGLFont::kBottom);
236 fAxisPainter->RefTMOff(0).Negate();
237 fAxisPainter->RnrLabels();
238 fAxisPainter->RnrLines();
241 TGLUtil::LineWidth(1);
244 TGLAxisPainter::LabVec_t& labs = fAxisPainter->RefLabVec();
247 TGLUtil::ColorTransparency(lineColor, alpha);
249 for (TGLAxisPainter::LabVec_t::iterator i = labs.begin(); i != labs.end(); ++i) {
250 tmp = vy1 + xdir * (i->first);
251 glVertex3dv(tmp.Arr());
252 tmp = vy2 + xdir * (i->first);
253 glVertex3dv(tmp.Arr());
260 TGLUtil::ColorTransparency(lineColor, alpha2);
261 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
262 glEnable(GL_LINE_STIPPLE);
263 glLineStipple(1, stipple);
267 Double_t omin = 0, omax = 0, bw1 = 0;
268 THLimitsFinder::Optimize(labs[0].second, labs[1].second, secSteps, omin, omax, ondiv, bw1);
269 Double_t val = labs[0].second;
270 while (val < fFrustum[2])
272 for (Int_t k=0; k<ondiv; k++)
275 tmp = vy1 + xdir * val;
276 glVertex3dv(tmp.Arr());
277 tmp = vy2 + xdir * val;
278 glVertex3dv(tmp.Arr());
281 val = labs[0].second - bw1;
282 while(val > fFrustum[0])
284 tmp = vy1 + xdir * val;
285 glVertex3dv(tmp.Arr());
286 tmp = vy2 + xdir * val;
287 glVertex3dv(tmp.Arr());
299 fAxis->SetTickLength(tlY);
300 fAxisPainter->RefDir() = ydir;
301 fAxis->SetLimits(minY, maxY);
302 fAxisPainter->RefTMOff(0) = xdir*rngX;
305 glTranslated(vx1.X(), vx1.Y(), vx1.Z());
306 fAxisPainter->SetLabelAlign(TGLFont::kLeft, TGLFont::kCenterV);
307 fAxisPainter->PaintAxis(rnrCtx, fAxis);
311 glTranslated(vx2.X(), vx2.Y(), vx2.Z());
312 fAxisPainter->SetLabelAlign(TGLFont::kRight, TGLFont::kCenterV);
313 fAxisPainter->RefTMOff(0).Negate();
314 fAxisPainter->RnrLabels();
315 fAxisPainter->RnrLines();
320 TGLAxisPainter::LabVec_t& labs = fAxisPainter->RefLabVec();
323 TGLUtil::ColorTransparency(lineColor, alpha);
325 for (TGLAxisPainter::LabVec_t::iterator i = labs.begin(); i != labs.end(); ++i) {
326 tmp = vx1 + ydir *(i->first);
327 glVertex3dv(tmp.Arr());
328 tmp = vx2 + ydir *(i->first);
329 glVertex3dv(tmp.Arr());
336 TGLUtil::ColorTransparency(lineColor, alpha2);
337 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
338 glEnable(GL_LINE_STIPPLE);
339 glLineStipple(1, stipple);
343 Double_t omin = 0, omax = 0, bw1 = 0;
345 THLimitsFinder::Optimize(labs[0].second, labs[1].second, secSteps, omin, omax, ondiv, bw1);
346 val = labs[0].second;
347 while(val < fFrustum[3])
349 for(Int_t k=0; k<ondiv; k++)
352 tmp = vx1 + ydir *val;
353 glVertex3dv(tmp.Arr());
354 tmp = vx2 + ydir * val;
355 glVertex3dv(tmp.Arr());
359 val = labs[0].second - bw1;
360 while(val > fFrustum[1])
362 tmp = vx1 + ydir *val;
363 glVertex3dv(tmp.Arr());
364 tmp = vx2 + ydir * val;
365 glVertex3dv(tmp.Arr());
377 void TGLCameraOverlay::RenderBar(TGLRnrCtx& rnrCtx)
380 Double_t wfrust = TMath::Abs(fFrustum[2]-fFrustum[0]);
381 Float_t barsize= 0.14* wfrust;
382 Int_t exp = (Int_t) TMath::Floor(TMath::Log10(barsize));
383 Double_t fact = barsize/TMath::Power(10, exp);
387 red = 5*TMath::Power(10, exp);
391 red = 2*TMath::Power(10, exp);
394 red = TMath::Power(10, exp);
398 TGLVector3 xdir = rnrCtx.RefCamera().GetCamBase().GetBaseVec(2);
399 TGLVector3 ydir = rnrCtx.RefCamera().GetCamBase().GetBaseVec(3);
403 TGLUtil::Color(rnrCtx.ColorSet().Foreground());
405 const char* txt = Form(
"%.*f", (exp < 0) ? -exp : 0, red);
408 rnrCtx.RegisterFont(12,
"arial", TGLFont::kPixmap, font);
409 font.BBox(txt, bb[0], bb[1], bb[2], bb[3], bb[4], bb[5]);
410 TGLRect &vp = rnrCtx.GetCamera()->RefViewport();
411 Double_t mH = (fFrustum[3]-fFrustum[1])*bb[4]/vp.Height();
413 v = xdir*(fFrustum[2]-barsize) + ydir*(fFrustum[3] - mH*1.5);
414 glTranslated(v.X(), v.Y(), v.Z());
419 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
420 TGLUtil::LineWidth(2.);
422 Float_t xt = fFrustum[2] - 1.1*barsize;
423 Float_t yt = fFrustum[3] - 2.1*mH;
424 v = xdir*xt + ydir*yt;
425 glTranslated(v.X(), v.Y(), v.Z());
430 glVertex3dv(v.Arr());
432 glVertex3dv(v.Arr());
434 v = xdir*barsize + ydir*mH;
435 glVertex3dv(v.Arr());
436 v = xdir*barsize - ydir*mH;
437 glVertex3dv(v.Arr());
439 TGLUtil::Color(kRed);
441 glVertex3dv(v.Arr());
443 glVertex3dv(v.Arr());
446 glVertex3dv(v.Arr());
448 glVertex3dv(v.Arr());
450 glVertex3d(0, 0., 0.);
452 glVertex3dv(v.Arr());
461 void TGLCameraOverlay::Render(TGLRnrCtx& rnrCtx)
463 TGLCamera &cam = rnrCtx.RefCamera();
465 if (rnrCtx.Selection() ||
466 (cam.IsPerspective() && ! fShowPerspective) ||
467 (cam.IsOrthographic() && ! fShowOrthographic))
472 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
474 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
476 TGLUtil::Color(rnrCtx.ColorSet().Markup());
477 TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
478 Float_t old_depth_range[2];
479 glGetFloatv(GL_DEPTH_RANGE, old_depth_range);
483 if (cam.IsOrthographic())
485 switch (fOrthographicMode)
488 glDepthRange(0, 0.1);
492 glDepthRange(0, 0.1);
493 RenderAxis(rnrCtx, kFALSE);
496 glDepthRange(0, 0.1);
497 RenderAxis(rnrCtx, kTRUE);
500 glDepthRange(1, 0.9);
501 RenderAxis(rnrCtx, kTRUE);
509 RenderPlaneIntersect(rnrCtx);
512 glDepthRange(old_depth_range[0], old_depth_range[1]);