56 ClassImp(TGLPhysicalShape);
66 TGLPhysicalShape::TGLPhysicalShape(UInt_t
id,
const TGLLogicalShape & logicalShape,
67 const TGLMatrix & transform, Bool_t invertedWind,
68 const Float_t rgba[4]) :
69 fLogicalShape (&logicalShape),
73 fTransform (transform),
76 fInvertedWind (invertedWind),
78 fIsScaleForRnr(kFALSE)
80 fLogicalShape->AddRef(
this);
95 TGLPhysicalShape::TGLPhysicalShape(UInt_t
id,
const TGLLogicalShape & logicalShape,
96 const Double_t * transform, Bool_t invertedWind,
97 const Float_t rgba[4]) :
98 fLogicalShape (&logicalShape),
102 fTransform (transform),
105 fInvertedWind (invertedWind),
107 fIsScaleForRnr(kFALSE)
109 fLogicalShape->AddRef(
this);
114 fTransform.Transpose3x3();
124 TGLPhysicalShape::~TGLPhysicalShape()
128 if (fLogicalShape) fLogicalShape->SubRef(
this);
131 while (fFirstPSRef) {
132 fFirstPSRef->SetPShape(0);
139 void TGLPhysicalShape::AddReference(TGLPShapeRef* ref)
143 ref->fNextPSRef = fFirstPSRef;
150 void TGLPhysicalShape::RemoveReference(TGLPShapeRef* ref)
154 Bool_t found = kFALSE;
155 if (fFirstPSRef == ref) {
156 fFirstPSRef = ref->fNextPSRef;
159 TGLPShapeRef *shp1 = fFirstPSRef, *shp2;
160 while ((shp2 = shp1->fNextPSRef) != 0) {
162 shp1->fNextPSRef = shp2->fNextPSRef;
172 Error(
"TGLPhysicalShape::RemoveReference",
"Attempt to un-ref an unregistered shape-ref.");
180 void TGLPhysicalShape::Modified()
183 TGLPShapeRef * ref = fFirstPSRef;
185 ref->PShapeModified();
186 ref = ref->fNextPSRef;
193 void TGLPhysicalShape::UpdateBoundingBox()
195 fBoundingBox.Set(fLogicalShape->BoundingBox());
196 fBoundingBox.Transform(fTransform);
198 fIsScaleForRnr = fTransform.IsScalingForRender();
200 if (fLogicalShape->GetScene())
201 fLogicalShape->GetScene()->InvalidateBoundingBox();
207 void TGLPhysicalShape::InitColor(
const Float_t rgba[4])
215 fColor[4] = fColor[5] = fColor[6] = 0.0f;
216 fColor[8] = fColor[9] = fColor[10] = 0.7f;
217 fColor[12] = fColor[13] = fColor[14] = 0.0f;
218 fColor[7] = fColor[11] = fColor[15] = 1.0f;
227 void TGLPhysicalShape::SetColor(
const Float_t color[17])
230 for (UInt_t i = 0; i < 17; i++) {
231 fColor[i] = color[i];
241 void TGLPhysicalShape::SetColorOnFamily(
const Float_t color[17])
243 TGLPhysicalShape* pshp =
const_cast<TGLPhysicalShape*
>(fLogicalShape->GetFirstPhysical());
246 pshp->SetColor(color);
247 pshp = pshp->fNextPhysical;
254 void TGLPhysicalShape::SetDiffuseColor(
const Float_t rgba[4])
256 for (Int_t i=0; i<4; ++i)
264 void TGLPhysicalShape::SetDiffuseColor(
const UChar_t rgba[4])
266 for (Int_t i=0; i<4; ++i)
267 fColor[i] = rgba[i]/255.0f;
275 void TGLPhysicalShape::SetDiffuseColor(Color_t ci, UChar_t transparency)
278 TColor* c = gROOT->GetColor(ci);
280 fColor[0] = c->GetRed();
281 fColor[1] = c->GetGreen();
282 fColor[2] = c->GetBlue();
283 fColor[3] = 1.0f - 0.01*transparency;
292 void TGLPhysicalShape::SetupGLColors(TGLRnrCtx & rnrCtx,
const Float_t* color)
const
294 if (color == 0) color = fColor;
296 switch (rnrCtx.DrawPass()) {
297 case TGLRnrCtx::kPassWireFrame:
303 case TGLRnrCtx::kPassFill:
304 case TGLRnrCtx::kPassOutlineFill:
312 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
313 glMaterialfv(GL_FRONT, GL_AMBIENT, color + 4);
314 glMaterialfv(GL_FRONT, GL_SPECULAR, color + 8);
315 glMaterialfv(GL_FRONT, GL_EMISSION, color + 12);
316 glMaterialf(GL_FRONT, GL_SHININESS, color[16]);
321 case TGLRnrCtx::kPassOutlineLine:
325 TGLUtil::ColorAlpha(rnrCtx.ColorSet().Outline(), 0.5f*color[3]);
338 void TGLPhysicalShape::Draw(TGLRnrCtx & rnrCtx)
const
342 Info(
"TGLPhysicalShape::Draw",
"this %ld (class %s) LOD %d",
343 (Long_t)
this, IsA()->GetName(), rnrCtx.ShapeLOD());
348 if (rnrCtx.ShapeLOD() == TGLRnrCtx::kLODPixel)
350 if (!rnrCtx.IsDrawPassOutlineLine())
354 glVertex3dv(&fTransform.CArr()[12]);
361 Info(
"TGLPhysicalShape::Draw",
"this %ld (class %s) LOD %d",
362 (Long_t)
this, IsA()->GetName(), rnrCtx.ShapeLOD());
366 glMultMatrixd(fTransform.CArr());
367 if (fIsScaleForRnr) glEnable(GL_NORMALIZE);
368 if (fInvertedWind) glFrontFace(GL_CW);
369 if (rnrCtx.Highlight())
371 glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
373 glDisable(GL_LIGHTING);
374 glDisable(GL_DEPTH_TEST);
376 if (rnrCtx.HighlightOutline())
378 static const Int_t offsets[20][2] =
379 { {-1,-1}, { 1,-1}, { 1, 1}, {-1, 1},
380 { 1, 0}, { 0, 1}, {-1, 0}, { 0,-1},
381 { 0,-2}, { 2, 0}, { 0, 2}, {-2, 0},
382 {-2,-2}, { 2,-2}, { 2, 2}, {-2, 2},
383 { 0,-3}, { 3, 0}, { 0, 3}, {-3, 0} };
384 static const Int_t max_off =
385 TGLUtil::GetScreenScalingFactor() > 1.5 ? 20 : 12;
387 const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
389 for (
int i = 0; i < max_off; ++i)
391 glViewport(vp.X() + offsets[i][0], vp.Y() + offsets[i][1], vp.Width(), vp.Height());
392 fLogicalShape->DrawHighlight(rnrCtx,
this);
395 glViewport(vp.X(), vp.Y(), vp.Width(), vp.Height());
399 fLogicalShape->DrawHighlight(rnrCtx,
this);
406 SetupGLColors(rnrCtx);
407 if (rnrCtx.IsDrawPassOutlineLine())
408 TGLUtil::LockColor();
409 fLogicalShape->Draw(rnrCtx);
410 if (rnrCtx.IsDrawPassOutlineLine())
411 TGLUtil::UnlockColor();
413 if (fInvertedWind) glFrontFace(GL_CCW);
414 if (fIsScaleForRnr) glDisable(GL_NORMALIZE);
431 void TGLPhysicalShape::CalculateShapeLOD(TGLRnrCtx& rnrCtx, Float_t& pixSize, Short_t& shapeLOD)
const
433 TGLLogicalShape::ELODAxes lodAxes = fLogicalShape->SupportedLODAxes();
435 if (lodAxes == TGLLogicalShape::kLODAxesNone)
441 shapeLOD = TGLRnrCtx::kLODHigh;
445 std::vector <Double_t> boxViewportDiags;
446 const TGLBoundingBox & box = BoundingBox();
447 const TGLCamera & camera = rnrCtx.RefCamera();
449 if (lodAxes == TGLLogicalShape::kLODAxesAll) {
452 boxViewportDiags.push_back(camera.ViewportRect(box).Diagonal());
453 }
else if (lodAxes == (TGLLogicalShape::kLODAxesY | TGLLogicalShape::kLODAxesZ)) {
456 boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceLowX).Diagonal());
457 boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceHighX).Diagonal());
458 }
else if (lodAxes == (TGLLogicalShape::kLODAxesX | TGLLogicalShape::kLODAxesZ)) {
460 boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceLowY).Diagonal());
461 boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceHighY).Diagonal());
462 }
else if (lodAxes == (TGLLogicalShape::kLODAxesX | TGLLogicalShape::kLODAxesY)) {
464 boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceLowZ).Diagonal());
465 boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceHighZ).Diagonal());
471 Error(
"TGLPhysicalShape::CalcPhysicalLOD",
"LOD calculation for single axis not implemented presently");
472 shapeLOD = TGLRnrCtx::kLODMed;
477 Double_t largestDiagonal = 0.0;
478 for (UInt_t i = 0; i < boxViewportDiags.size(); i++) {
479 if (boxViewportDiags[i] > largestDiagonal) {
480 largestDiagonal = boxViewportDiags[i];
483 pixSize = largestDiagonal;
485 if (largestDiagonal <= 1.0) {
486 shapeLOD = TGLRnrCtx::kLODPixel;
491 UInt_t lodApp =
static_cast<UInt_t
>(std::pow(largestDiagonal,0.4) * 100.0 / std::pow(2000.0,0.4));
492 if (lodApp > 1000) lodApp = 1000;
493 shapeLOD = (Short_t) lodApp;
501 void TGLPhysicalShape::QuantizeShapeLOD(Short_t shapeLOD, Short_t combiLOD, Short_t& quantLOD)
const
503 quantLOD = fLogicalShape->QuantizeShapeLOD(shapeLOD, combiLOD);
510 void TGLPhysicalShape::InvokeContextMenu(TContextMenu & menu, UInt_t x, UInt_t y)
const
513 fLogicalShape->InvokeContextMenu(menu, x, y);