00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TEveBoxSetGL.h"
00013 #include "TEveBoxSet.h"
00014 #include "TEveFrameBoxGL.h"
00015
00016 #include "TGLIncludes.h"
00017 #include "TGLRnrCtx.h"
00018 #include "TGLSelectRecord.h"
00019 #include "TGLQuadric.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 ClassImp(TEveBoxSetGL);
00032
00033
00034 TEveBoxSetGL::TEveBoxSetGL() : TEveDigitSetGL(), fM(0), fBoxDL(0)
00035 {
00036
00037
00038
00039 fMultiColor = kTRUE;
00040 }
00041
00042
00043 TEveBoxSetGL::~TEveBoxSetGL()
00044 {
00045
00046
00047 DLCachePurge();
00048 }
00049
00050
00051
00052
00053
00054
00055 Int_t TEveBoxSetGL::PrimitiveType() const
00056 {
00057
00058
00059
00060 return (fM->fRenderMode != TEveDigitSet::kRM_Line) ? GL_QUADS : GL_LINE_LOOP;
00061 }
00062
00063
00064 void TEveBoxSetGL::MakeOriginBox(Float_t p[8][3], Float_t dx, Float_t dy, Float_t dz) const
00065 {
00066
00067
00068
00069 p[0][0] = 0; p[0][1] = dy; p[0][2] = 0;
00070 p[1][0] = dx; p[1][1] = dy; p[1][2] = 0;
00071 p[2][0] = dx; p[2][1] = 0; p[2][2] = 0;
00072 p[3][0] = 0; p[3][1] = 0; p[3][2] = 0;
00073
00074 p[4][0] = 0; p[4][1] = dy; p[4][2] = dz;
00075 p[5][0] = dx; p[5][1] = dy; p[5][2] = dz;
00076 p[6][0] = dx; p[6][1] = 0; p[6][2] = dz;
00077 p[7][0] = 0; p[7][1] = 0; p[7][2] = dz;
00078 }
00079
00080
00081 inline void TEveBoxSetGL::RenderBoxStdNorm(const Float_t p[8][3]) const
00082 {
00083
00084
00085
00086
00087 glNormal3f(0, 0, -1);
00088 glVertex3fv(p[0]); glVertex3fv(p[1]);
00089 glVertex3fv(p[2]); glVertex3fv(p[3]);
00090
00091 glNormal3f(0, 0, 1);
00092 glVertex3fv(p[7]); glVertex3fv(p[6]);
00093 glVertex3fv(p[5]); glVertex3fv(p[4]);
00094
00095 glNormal3f(0, 1, 0);
00096 glVertex3fv(p[0]); glVertex3fv(p[4]);
00097 glVertex3fv(p[5]); glVertex3fv(p[1]);
00098
00099 glNormal3f(0, -1, 0);
00100 glVertex3fv(p[3]); glVertex3fv(p[2]);
00101 glVertex3fv(p[6]); glVertex3fv(p[7]);
00102
00103 glNormal3f(-1, 0, 0);
00104 glVertex3fv(p[0]); glVertex3fv(p[3]);
00105 glVertex3fv(p[7]); glVertex3fv(p[4]);
00106
00107 glNormal3f(1, 0, 0);
00108 glVertex3fv(p[1]); glVertex3fv(p[5]);
00109 glVertex3fv(p[6]); glVertex3fv(p[2]);
00110 }
00111
00112 namespace
00113 {
00114 void subtract_and_normalize(const Float_t a[3], const Float_t b[3],
00115 Float_t o[3])
00116 {
00117
00118 o[0] = a[0] - b[0];
00119 o[1] = a[1] - b[1];
00120 o[2] = a[2] - b[2];
00121 Float_t d = sqrtf(o[0]*o[0] + o[1]*o[1] + o[2]*o[2]);
00122 if (d != 0)
00123 {
00124 d = 1.0f / d;
00125 o[0] *= d;
00126 o[1] *= d;
00127 o[2] *= d;
00128 }
00129 }
00130 }
00131
00132 void TEveBoxSetGL::RenderBoxAutoNorm(const Float_t p[8][3]) const
00133 {
00134
00135
00136 Float_t e[6][3], n[3];
00137 subtract_and_normalize(p[1], p[0], e[0]);
00138 subtract_and_normalize(p[3], p[0], e[1]);
00139 subtract_and_normalize(p[4], p[0], e[2]);
00140 subtract_and_normalize(p[5], p[6], e[3]);
00141 subtract_and_normalize(p[7], p[6], e[4]);
00142 subtract_and_normalize(p[2], p[6], e[5]);
00143
00144
00145 glNormal3fv(TMath::Cross(e[0], e[1], n));
00146 glVertex3fv(p[0]); glVertex3fv(p[1]);
00147 glVertex3fv(p[2]); glVertex3fv(p[3]);
00148
00149 glNormal3fv(TMath::Cross(e[3], e[4], n));
00150 glVertex3fv(p[7]); glVertex3fv(p[6]);
00151 glVertex3fv(p[5]); glVertex3fv(p[4]);
00152
00153 glNormal3fv(TMath::Cross(e[2], e[0], n));
00154 glVertex3fv(p[0]); glVertex3fv(p[4]);
00155 glVertex3fv(p[5]); glVertex3fv(p[1]);
00156
00157 glNormal3fv(TMath::Cross(e[4], e[5], n));
00158 glVertex3fv(p[3]); glVertex3fv(p[2]);
00159 glVertex3fv(p[6]); glVertex3fv(p[7]);
00160
00161 glNormal3fv(TMath::Cross(e[1], e[2], n));
00162 glVertex3fv(p[0]); glVertex3fv(p[3]);
00163 glVertex3fv(p[7]); glVertex3fv(p[4]);
00164
00165 glNormal3fv(TMath::Cross(e[5], e[3], n));
00166 glVertex3fv(p[1]); glVertex3fv(p[5]);
00167 glVertex3fv(p[6]); glVertex3fv(p[2]);
00168 }
00169
00170
00171 void TEveBoxSetGL::MakeDisplayList() const
00172 {
00173
00174
00175
00176
00177
00178 if (fM->fBoxType == TEveBoxSet::kBT_AABox ||
00179 fM->fBoxType == TEveBoxSet::kBT_AABoxFixedDim ||
00180 fM->fBoxType == TEveBoxSet::kBT_Cone ||
00181 fM->fBoxType == TEveBoxSet::kBT_EllipticCone)
00182 {
00183 if (fBoxDL == 0)
00184 fBoxDL = glGenLists(1);
00185
00186 glNewList(fBoxDL, GL_COMPILE);
00187
00188 if (fM->fBoxType < TEveBoxSet::kBT_Cone)
00189 {
00190 glBegin(PrimitiveType());
00191 Float_t p[8][3];
00192 if (fM->fBoxType == TEveBoxSet::kBT_AABox)
00193 MakeOriginBox(p, 1.0f, 1.0f, 1.0f);
00194 else
00195 MakeOriginBox(p, fM->fDefWidth, fM->fDefHeight, fM->fDefDepth);
00196 RenderBoxStdNorm(p);
00197 glEnd();
00198 }
00199 else
00200 {
00201 static TGLQuadric quad;
00202 Int_t nt = 15;
00203 gluCylinder(quad.Get(), 0, 1, 1, nt, 1);
00204
00205 if (fM->fDrawConeCap)
00206 {
00207 glPushMatrix();
00208 glTranslatef(0, 0, 1);
00209 gluDisk(quad.Get(), 0, 1, nt, 1);
00210 glPopMatrix();
00211 }
00212 }
00213
00214 glEndList();
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223 Bool_t TEveBoxSetGL::ShouldDLCache(const TGLRnrCtx& rnrCtx) const
00224 {
00225
00226
00227
00228 MakeDisplayList();
00229
00230 return TEveDigitSetGL::ShouldDLCache(rnrCtx);
00231 }
00232
00233
00234 void TEveBoxSetGL::DLCacheDrop()
00235 {
00236
00237
00238
00239
00240 fBoxDL = 0;
00241 TGLObject::DLCacheDrop();
00242 }
00243
00244
00245 void TEveBoxSetGL::DLCachePurge()
00246 {
00247
00248
00249
00250 if (fBoxDL != 0)
00251 {
00252 PurgeDLRange(fBoxDL, 1);
00253 fBoxDL = 0;
00254 }
00255 TGLObject::DLCachePurge();
00256 }
00257
00258
00259
00260
00261 Bool_t TEveBoxSetGL::SetModel(TObject* obj, const Option_t* )
00262 {
00263
00264
00265
00266 fM = SetModelDynCast<TEveBoxSet>(obj);
00267 return kTRUE;
00268 }
00269
00270
00271
00272 namespace
00273 {
00274 inline void AntiFlick(Float_t x, Float_t y, Float_t z)
00275 {
00276
00277 glBegin(GL_POINTS);
00278 glVertex3f(x, y, z);
00279 glEnd();
00280 }
00281 }
00282
00283
00284
00285
00286 void TEveBoxSetGL::RenderBoxes(TGLRnrCtx& rnrCtx) const
00287 {
00288
00289
00290 static const TEveException eH("TEveBoxSetGL::RenderBoxes ");
00291
00292 if (rnrCtx.SecSelection()) glPushName(0);
00293
00294 Int_t boxSkip = 0;
00295 if (rnrCtx.ShapeLOD() < 50)
00296 boxSkip = 6 - (rnrCtx.ShapeLOD()+1)/10;
00297
00298 TEveChunkManager::iterator bi(fM->fPlex);
00299 if (rnrCtx.Highlight() && fHighlightSet)
00300 bi.fSelection = fHighlightSet;
00301
00302 switch (fM->fBoxType)
00303 {
00304
00305 case TEveBoxSet::kBT_FreeBox:
00306 {
00307 GLenum primitiveType = PrimitiveType();
00308 while (bi.next())
00309 {
00310 TEveBoxSet::BFreeBox_t& b = * (TEveBoxSet::BFreeBox_t*) bi();
00311 if (SetupColor(b))
00312 {
00313 if (rnrCtx.SecSelection()) glLoadName(bi.index());
00314 glBegin(primitiveType);
00315 RenderBoxAutoNorm(b.fVertices);
00316 glEnd();
00317 if (fM->fAntiFlick)
00318 AntiFlick(0.5f*(b.fVertices[0][0] + b.fVertices[6][0]),
00319 0.5f*(b.fVertices[0][1] + b.fVertices[6][1]),
00320 0.5f*(b.fVertices[0][2] + b.fVertices[6][2]));
00321 }
00322 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
00323 }
00324 break;
00325 }
00326
00327 case TEveBoxSet::kBT_AABox:
00328 {
00329 glEnable(GL_NORMALIZE);
00330 while (bi.next())
00331 {
00332 TEveBoxSet::BAABox_t& b = * (TEveBoxSet::BAABox_t*) bi();
00333 if (SetupColor(b))
00334 {
00335 if (rnrCtx.SecSelection()) glLoadName(bi.index());
00336 glPushMatrix();
00337 glTranslatef(b.fA, b.fB, b.fC);
00338 glScalef (b.fW, b.fH, b.fD);
00339 glCallList(fBoxDL);
00340 if (fM->fAntiFlick)
00341 AntiFlick(0.5f, 0.5f, 0.5f);
00342 glPopMatrix();
00343 }
00344 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
00345 }
00346 break;
00347 }
00348
00349 case TEveBoxSet::kBT_AABoxFixedDim:
00350 {
00351 while (bi.next())
00352 {
00353 TEveBoxSet::BAABoxFixedDim_t& b = * (TEveBoxSet::BAABoxFixedDim_t*) bi();
00354 if (SetupColor(b))
00355 {
00356 if (rnrCtx.SecSelection()) glLoadName(bi.index());
00357 glTranslatef(b.fA, b.fB, b.fC);
00358 glCallList(fBoxDL);
00359 if (fM->fAntiFlick)
00360 AntiFlick(0.5f*fM->fDefWidth, 0.5f*fM->fDefHeight, 0.5f*fM->fDefDepth);
00361 glTranslatef(-b.fA, -b.fB, -b.fC);
00362 }
00363 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
00364 }
00365 break;
00366 }
00367
00368 case TEveBoxSet::kBT_Cone:
00369 {
00370 using namespace TMath;
00371
00372 glEnable(GL_NORMALIZE);
00373 Float_t theta=0, phi=0, h=0;
00374 while (bi.next())
00375 {
00376 TEveBoxSet::BCone_t& b = * (TEveBoxSet::BCone_t*) bi();
00377 if (SetupColor(b))
00378 {
00379 if (rnrCtx.SecSelection()) glLoadName(bi.index());
00380 h = b.fDir.Mag();
00381 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
00382 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
00383 glPushMatrix();
00384 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
00385 glRotatef(phi, 0, 0, 1);
00386 glRotatef(90 - theta, 0, 1, 0);
00387 glScalef (b.fR, b.fR, h);
00388 glCallList(fBoxDL);
00389 if (fM->fAntiFlick)
00390 AntiFlick(0.0f, 0.0f, 0.5f);
00391 glPopMatrix();
00392 }
00393 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
00394 }
00395 break;
00396 }
00397
00398 case TEveBoxSet::kBT_EllipticCone:
00399 {
00400 using namespace TMath;
00401
00402 glEnable(GL_NORMALIZE);
00403 Float_t theta=0, phi=0, h=0;
00404 while (bi.next())
00405 {
00406 TEveBoxSet::BEllipticCone_t& b = * (TEveBoxSet::BEllipticCone_t*) bi();
00407 if (SetupColor(b))
00408 {
00409 if (rnrCtx.SecSelection()) glLoadName(bi.index());
00410 h = b.fDir.Mag();
00411 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
00412 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
00413 glPushMatrix();
00414 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
00415 glRotatef(phi, 0, 0, 1);
00416 glRotatef(90 - theta, 0, 1, 0);
00417 glRotatef(b.fAngle, 0, 0, 1);
00418 glScalef (b.fR, b.fR2, h);
00419 glCallList(fBoxDL);
00420 if (fM->fAntiFlick)
00421 AntiFlick(0.0f, 0.0f, 0.5f);
00422 glPopMatrix();
00423 }
00424 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
00425 }
00426 break;
00427 }
00428
00429 default:
00430 {
00431 throw(eH + "unsupported box-type.");
00432 }
00433
00434 }
00435
00436 if (rnrCtx.SecSelection()) glPopName();
00437 }
00438
00439
00440 void TEveBoxSetGL::DirectDraw(TGLRnrCtx& rnrCtx) const
00441 {
00442
00443
00444
00445 TEveBoxSet& mB = * fM;
00446
00447
00448 if (mB.fPlex.Size() > 0)
00449 {
00450 if (! mB.fSingleColor && ! mB.fValueIsColor && mB.fPalette == 0)
00451 {
00452 mB.AssertPalette();
00453 }
00454
00455 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
00456
00457 if ( ! rnrCtx.IsDrawPassOutlineLine())
00458 {
00459 if (mB.fRenderMode == TEveDigitSet::kRM_Fill)
00460 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00461 else if (mB.fRenderMode == TEveDigitSet::kRM_Line)
00462 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00463 }
00464
00465 if (mB.fBoxType == TEveBoxSet::kBT_Cone ||
00466 mB.fBoxType == TEveBoxSet::kBT_EllipticCone)
00467 {
00468 glDisable(GL_CULL_FACE);
00469 }
00470
00471 if (mB.fDisableLighting) glDisable(GL_LIGHTING);
00472
00473 RenderBoxes(rnrCtx);
00474
00475 glPopAttrib();
00476 }
00477
00478 if (mB.fFrame != 0 && ! rnrCtx.SecSelection() &&
00479 ! (rnrCtx.Highlight() && AlwaysSecondarySelect()))
00480 {
00481 TEveFrameBoxGL::Render(mB.fFrame);
00482 }
00483 }
00484
00485
00486 void TEveBoxSetGL::Render(TGLRnrCtx& rnrCtx)
00487 {
00488
00489
00490
00491 MakeDisplayList();
00492 DirectDraw(rnrCtx);
00493 glDeleteLists(fBoxDL, 1);
00494 fBoxDL = 0;
00495 }