25 ClassImp(TEveBoxSetGL);
30 TEveBoxSetGL::TEveBoxSetGL() : TEveDigitSetGL(), fM(0), fBoxDL(0)
39 TEveBoxSetGL::~TEveBoxSetGL()
48 Int_t TEveBoxSetGL::PrimitiveType()
const
50 return (fM->fRenderMode != TEveDigitSet::kRM_Line) ? GL_QUADS : GL_LINE_LOOP;
56 void TEveBoxSetGL::MakeOriginBox(Float_t p[8][3], Float_t dx, Float_t dy, Float_t dz)
const
59 p[0][0] = 0; p[0][1] = dy; p[0][2] = 0;
60 p[1][0] = dx; p[1][1] = dy; p[1][2] = 0;
61 p[2][0] = dx; p[2][1] = 0; p[2][2] = 0;
62 p[3][0] = 0; p[3][1] = 0; p[3][2] = 0;
64 p[4][0] = 0; p[4][1] = dy; p[4][2] = dz;
65 p[5][0] = dx; p[5][1] = dy; p[5][2] = dz;
66 p[6][0] = dx; p[6][1] = 0; p[6][2] = dz;
67 p[7][0] = 0; p[7][1] = 0; p[7][2] = dz;
74 inline void TEveBoxSetGL::RenderBoxStdNorm(
const Float_t p[8][3])
const
78 glVertex3fv(p[0]); glVertex3fv(p[1]);
79 glVertex3fv(p[2]); glVertex3fv(p[3]);
82 glVertex3fv(p[7]); glVertex3fv(p[6]);
83 glVertex3fv(p[5]); glVertex3fv(p[4]);
86 glVertex3fv(p[0]); glVertex3fv(p[4]);
87 glVertex3fv(p[5]); glVertex3fv(p[1]);
90 glVertex3fv(p[3]); glVertex3fv(p[2]);
91 glVertex3fv(p[6]); glVertex3fv(p[7]);
94 glVertex3fv(p[0]); glVertex3fv(p[3]);
95 glVertex3fv(p[7]); glVertex3fv(p[4]);
98 glVertex3fv(p[1]); glVertex3fv(p[5]);
99 glVertex3fv(p[6]); glVertex3fv(p[2]);
104 void subtract_and_normalize(
const Float_t a[3],
const Float_t b[3],
111 Float_t d = sqrtf(o[0]*o[0] + o[1]*o[1] + o[2]*o[2]);
124 void TEveBoxSetGL::RenderBoxAutoNorm(
const Float_t p[8][3])
const
126 Float_t e[6][3], n[3];
127 subtract_and_normalize(p[1], p[0], e[0]);
128 subtract_and_normalize(p[3], p[0], e[1]);
129 subtract_and_normalize(p[4], p[0], e[2]);
130 subtract_and_normalize(p[5], p[6], e[3]);
131 subtract_and_normalize(p[7], p[6], e[4]);
132 subtract_and_normalize(p[2], p[6], e[5]);
135 glNormal3fv(TMath::Cross(e[0], e[1], n));
136 glVertex3fv(p[0]); glVertex3fv(p[1]);
137 glVertex3fv(p[2]); glVertex3fv(p[3]);
139 glNormal3fv(TMath::Cross(e[3], e[4], n));
140 glVertex3fv(p[7]); glVertex3fv(p[6]);
141 glVertex3fv(p[5]); glVertex3fv(p[4]);
143 glNormal3fv(TMath::Cross(e[2], e[0], n));
144 glVertex3fv(p[0]); glVertex3fv(p[4]);
145 glVertex3fv(p[5]); glVertex3fv(p[1]);
147 glNormal3fv(TMath::Cross(e[4], e[5], n));
148 glVertex3fv(p[3]); glVertex3fv(p[2]);
149 glVertex3fv(p[6]); glVertex3fv(p[7]);
151 glNormal3fv(TMath::Cross(e[1], e[2], n));
152 glVertex3fv(p[0]); glVertex3fv(p[3]);
153 glVertex3fv(p[7]); glVertex3fv(p[4]);
155 glNormal3fv(TMath::Cross(e[5], e[3], n));
156 glVertex3fv(p[1]); glVertex3fv(p[5]);
157 glVertex3fv(p[6]); glVertex3fv(p[2]);
166 void TEveBoxSetGL::MakeDisplayList()
const
168 if (fM->fBoxType == TEveBoxSet::kBT_AABox ||
169 fM->fBoxType == TEveBoxSet::kBT_AABoxFixedDim ||
170 fM->fBoxType == TEveBoxSet::kBT_Cone ||
171 fM->fBoxType == TEveBoxSet::kBT_EllipticCone ||
172 fM->fBoxType == TEveBoxSet::kBT_Hex)
175 fBoxDL = glGenLists(1);
177 glNewList(fBoxDL, GL_COMPILE);
179 if (fM->fBoxType < TEveBoxSet::kBT_Cone)
181 glBegin(PrimitiveType());
183 if (fM->fBoxType == TEveBoxSet::kBT_AABox)
184 MakeOriginBox(p, 1.0f, 1.0f, 1.0f);
186 MakeOriginBox(p, fM->fDefWidth, fM->fDefHeight, fM->fDefDepth);
190 else if (fM->fBoxType < TEveBoxSet::kBT_Hex)
192 static TGLQuadric quad;
194 gluCylinder(quad.Get(), 0, 1, 1, nt, 1);
196 if (fM->fDrawConeCap)
199 glTranslatef(0, 0, 1);
200 gluDisk(quad.Get(), 0, 1, nt, 1);
206 static TGLQuadric quad;
208 gluCylinder(quad.Get(), 1, 1, 1, nt, 1);
210 gluQuadricOrientation(quad.Get(), GLU_INSIDE);
211 gluDisk(quad.Get(), 0, 1, nt, 1);
212 gluQuadricOrientation(quad.Get(), GLU_OUTSIDE);
215 glTranslatef(0, 0, 1);
216 gluDisk(quad.Get(), 0, 1, nt, 1);
222 TGLUtil::CheckError(
"TEveBoxSetGL::MakeDisplayList");
230 Bool_t TEveBoxSetGL::ShouldDLCache(
const TGLRnrCtx& rnrCtx)
const
232 return TEveDigitSetGL::ShouldDLCache(rnrCtx);
240 void TEveBoxSetGL::DLCacheDrop()
243 TGLObject::DLCacheDrop();
250 void TEveBoxSetGL::DLCachePurge()
254 PurgeDLRange(fBoxDL, 1);
257 TGLObject::DLCachePurge();
264 Bool_t TEveBoxSetGL::SetModel(TObject* obj,
const Option_t* )
266 fM = SetModelDynCast<TEveBoxSet>(obj);
272 inline void AntiFlick(Float_t x, Float_t y, Float_t z)
284 void TEveBoxSetGL::RenderBoxes(TGLRnrCtx& rnrCtx)
const
286 static const TEveException eH(
"TEveBoxSetGL::RenderBoxes ");
288 if (rnrCtx.SecSelection()) glPushName(0);
291 if (fM->fBoxSkip > 0 && rnrCtx.CombiLOD() < TGLRnrCtx::kLODHigh &&
292 !rnrCtx.SecSelection())
294 boxSkip = TMath::Nint(TMath::Power(fM->fBoxSkip, 2.0 - 0.02*rnrCtx.CombiLOD()));
297 TEveChunkManager::iterator bi(fM->fPlex);
298 if (rnrCtx.Highlight() && fHighlightSet)
299 bi.fSelection = fHighlightSet;
301 switch (fM->fBoxType)
304 case TEveBoxSet::kBT_FreeBox:
306 GLenum primitiveType = PrimitiveType();
309 TEveBoxSet::BFreeBox_t& b = * (TEveBoxSet::BFreeBox_t*) bi();
312 if (rnrCtx.SecSelection()) glLoadName(bi.index());
313 glBegin(primitiveType);
314 RenderBoxAutoNorm(b.fVertices);
317 AntiFlick(0.5f*(b.fVertices[0][0] + b.fVertices[6][0]),
318 0.5f*(b.fVertices[0][1] + b.fVertices[6][1]),
319 0.5f*(b.fVertices[0][2] + b.fVertices[6][2]));
321 if (boxSkip) { Int_t s = boxSkip;
while (s--) bi.next(); }
326 case TEveBoxSet::kBT_AABox:
328 glEnable(GL_NORMALIZE);
331 TEveBoxSet::BAABox_t& b = * (TEveBoxSet::BAABox_t*) bi();
334 if (rnrCtx.SecSelection()) glLoadName(bi.index());
336 glTranslatef(b.fA, b.fB, b.fC);
337 glScalef (b.fW, b.fH, b.fD);
340 AntiFlick(0.5f, 0.5f, 0.5f);
343 if (boxSkip) { Int_t s = boxSkip;
while (s--) bi.next(); }
348 case TEveBoxSet::kBT_AABoxFixedDim:
352 TEveBoxSet::BAABoxFixedDim_t& b = * (TEveBoxSet::BAABoxFixedDim_t*) bi();
355 if (rnrCtx.SecSelection()) glLoadName(bi.index());
356 glTranslatef(b.fA, b.fB, b.fC);
359 AntiFlick(0.5f*fM->fDefWidth, 0.5f*fM->fDefHeight, 0.5f*fM->fDefDepth);
360 glTranslatef(-b.fA, -b.fB, -b.fC);
362 if (boxSkip) { Int_t s = boxSkip;
while (s--) bi.next(); }
367 case TEveBoxSet::kBT_Cone:
369 using namespace TMath;
371 glEnable(GL_NORMALIZE);
372 Float_t theta=0, phi=0, h=0;
375 TEveBoxSet::BCone_t& b = * (TEveBoxSet::BCone_t*) bi();
378 if (rnrCtx.SecSelection()) glLoadName(bi.index());
380 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
381 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
383 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
384 glRotatef(phi, 0, 0, 1);
385 glRotatef(90 - theta, 0, 1, 0);
386 glScalef (b.fR, b.fR, h);
389 AntiFlick(0.0f, 0.0f, 0.5f);
392 if (boxSkip) { Int_t s = boxSkip;
while (s--) bi.next(); }
397 case TEveBoxSet::kBT_EllipticCone:
399 using namespace TMath;
401 glEnable(GL_NORMALIZE);
402 Float_t theta=0, phi=0, h=0;
405 TEveBoxSet::BEllipticCone_t& b = * (TEveBoxSet::BEllipticCone_t*) bi();
408 if (rnrCtx.SecSelection()) glLoadName(bi.index());
410 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
411 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
413 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
414 glRotatef(phi, 0, 0, 1);
415 glRotatef(90 - theta, 0, 1, 0);
416 glRotatef(b.fAngle, 0, 0, 1);
417 glScalef (b.fR, b.fR2, h);
420 AntiFlick(0.0f, 0.0f, 0.5f);
423 if (boxSkip) { Int_t s = boxSkip;
while (s--) bi.next(); }
428 case TEveBoxSet::kBT_Hex:
430 using namespace TMath;
432 glEnable(GL_NORMALIZE);
435 TEveBoxSet::BHex_t& h = * (TEveBoxSet::BHex_t*) bi();
438 if (rnrCtx.SecSelection()) glLoadName(bi.index());
440 glTranslatef(h.fPos.fX, h.fPos.fY, h.fPos.fZ);
441 glRotatef(h.fAngle, 0, 0, 1);
442 glScalef (h.fR, h.fR, h.fDepth);
445 AntiFlick(0.0f, 0.0f, 0.5f);
448 if (boxSkip) { Int_t s = boxSkip;
while (s--) bi.next(); }
455 throw eH +
"unsupported box-type.";
460 if (rnrCtx.SecSelection()) glPopName();
467 void TEveBoxSetGL::DirectDraw(TGLRnrCtx& rnrCtx)
const
469 TEveBoxSet& mB = * fM;
472 if (mB.fPlex.Size() > 0)
476 if (! mB.fSingleColor && ! mB.fValueIsColor && mB.fPalette == 0)
481 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
483 if ( ! rnrCtx.IsDrawPassOutlineLine())
485 if (mB.fRenderMode == TEveDigitSet::kRM_Fill)
486 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
487 else if (mB.fRenderMode == TEveDigitSet::kRM_Line)
488 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
491 if (mB.fBoxType == TEveBoxSet::kBT_Cone ||
492 mB.fBoxType == TEveBoxSet::kBT_EllipticCone)
494 glDisable(GL_CULL_FACE);
497 if (mB.fDisableLighting) glDisable(GL_LIGHTING);
504 DrawFrameIfNeeded(rnrCtx);
511 void TEveBoxSetGL::Render(TGLRnrCtx& rnrCtx)