00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TGLSceneBase.h"
00013 #include "TGLSceneInfo.h"
00014 #include "TGLViewerBase.h"
00015 #include "TGLRnrCtx.h"
00016 #include "TGLCamera.h"
00017 #include "TGLClip.h"
00018 #include "TGLIncludes.h"
00019
00020 #include <TMath.h>
00021
00022 #include <string>
00023 #include <algorithm>
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 ClassImp(TGLSceneBase);
00049
00050 UInt_t TGLSceneBase::fgSceneIDSrc = 1;
00051
00052
00053 TGLSceneBase::TGLSceneBase() :
00054 TGLLockable(),
00055
00056 fTimeStamp (1),
00057 fMinorStamp (1),
00058 fLOD (TGLRnrCtx::kLODHigh),
00059 fStyle (TGLRnrCtx::kStyleUndef),
00060 fWFLineW (0),
00061 fOLLineW (0),
00062 fClip (0),
00063 fSelectable (kTRUE),
00064 fBoundingBox (),
00065 fBoundingBoxValid (kFALSE),
00066 fDoFrustumCheck (kTRUE),
00067 fDoClipCheck (kTRUE),
00068 fAutoDestruct (kTRUE)
00069 {
00070
00071
00072 fSceneID = fgSceneIDSrc++;
00073 fName = Form("unnamed-%d", fSceneID);
00074 }
00075
00076
00077 TGLSceneBase::~TGLSceneBase()
00078 {
00079
00080
00081 for (ViewerList_i i=fViewers.begin(); i!=fViewers.end(); ++i)
00082 {
00083 (*i)->SceneDestructing(this);
00084 }
00085 }
00086
00087
00088 void TGLSceneBase::AddViewer(TGLViewerBase* viewer)
00089 {
00090
00091
00092 ViewerList_i i = std::find(fViewers.begin(), fViewers.end(), viewer);
00093 if (i == fViewers.end())
00094 fViewers.push_back(viewer);
00095 else
00096 Warning("TGLSceneBase::AddViewer", "viewer already in the list.");
00097 }
00098
00099
00100 void TGLSceneBase::RemoveViewer(TGLViewerBase* viewer)
00101 {
00102
00103
00104
00105
00106 ViewerList_i i = std::find(fViewers.begin(), fViewers.end(), viewer);
00107 if (i != fViewers.end())
00108 fViewers.erase(i);
00109 else
00110 Warning("TGLSceneBase::RemoveViewer", "viewer not found in the list.");
00111
00112 if (fViewers.empty() && fAutoDestruct)
00113 {
00114 if (gDebug > 0)
00115 Info("TGLSceneBase::RemoveViewer", "scene '%s' not used - autodestructing.", GetName());
00116 delete this;
00117 }
00118 }
00119
00120 void TGLSceneBase::TagViewersChanged()
00121 {
00122
00123
00124 for (ViewerList_i i=fViewers.begin(); i!=fViewers.end(); ++i)
00125 {
00126 (*i)->Changed();
00127 }
00128 }
00129
00130
00131
00132
00133 const char* TGLSceneBase::LockIdStr() const
00134 {
00135
00136
00137 return Form("TGLSceneBase %s", fName.Data());
00138 }
00139
00140
00141
00142
00143
00144
00145 TGLSceneInfo* TGLSceneBase::CreateSceneInfo(TGLViewerBase* view)
00146 {
00147
00148
00149
00150 return new TGLSceneInfo(view, this);
00151 }
00152
00153
00154 void TGLSceneBase::RebuildSceneInfo(TGLRnrCtx& ctx)
00155 {
00156
00157
00158
00159
00160 TGLSceneInfo* sinfo = ctx.GetSceneInfo();
00161
00162 sinfo->SetLastClip(0);
00163 sinfo->SetLastCamera(0);
00164 }
00165
00166
00167 void TGLSceneBase::UpdateSceneInfo(TGLRnrCtx& ctx)
00168 {
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 if (gDebug > 3)
00179 {
00180 Info("TGLSceneBase::UpdateSceneInfo",
00181 "'%s' timestamp=%u",
00182 GetName(), fTimeStamp);
00183 }
00184
00185 TGLSceneInfo* sinfo = ctx.GetSceneInfo();
00186
00187
00188
00189
00190
00191 sinfo->SetLastLOD (TGLRnrCtx::kLODUndef);
00192 sinfo->SetLastStyle (TGLRnrCtx::kStyleUndef);
00193 sinfo->SetSceneStamp(fTimeStamp);
00194
00195 sinfo->InFrustum (kTRUE);
00196 sinfo->InClip (kTRUE);
00197 sinfo->ClipMode (TGLSceneInfo::kClipNone);
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 sinfo->SetLastClip(0);
00214 sinfo->FrustumPlanes().clear();
00215 sinfo->ClipPlanes().clear();
00216
00217 if (fDoFrustumCheck)
00218 {
00219 for (Int_t i=0; i<TGLCamera::kPlanesPerFrustum; ++i)
00220 {
00221 TGLPlane p = ctx.GetCamera()->FrustumPlane((TGLCamera::EFrustumPlane)i);
00222
00223 switch (BoundingBox().Overlap(p))
00224 {
00225 case kInside:
00226 break;
00227 case kPartial:
00228 sinfo->FrustumPlanes().push_back(p);
00229 break;
00230 case kOutside:
00231 sinfo->InFrustum(kFALSE);
00232 break;
00233 }
00234 }
00235 }
00236
00237 if (fDoClipCheck && ctx.HasClip())
00238 {
00239 if (ctx.Clip()->GetMode() == TGLClip::kOutside)
00240 sinfo->ClipMode(TGLSceneInfo::kClipOutside);
00241 else
00242 sinfo->ClipMode(TGLSceneInfo::kClipInside);
00243
00244 std::vector<TGLPlane> planeSet;
00245 ctx.Clip()->PlaneSet(planeSet);
00246
00247
00248 std::vector<TGLPlane>::iterator it = planeSet.begin();
00249 while (it != planeSet.end())
00250 {
00251
00252 switch (BoundingBox().Overlap(*it))
00253 {
00254 case kInside:
00255 break;
00256 case kPartial:
00257 sinfo->ClipPlanes().push_back(*it);
00258 break;
00259 case kOutside:
00260 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
00261 {
00262
00263 sinfo->InClip(kFALSE);
00264 }
00265 else
00266 {
00267
00268
00269 sinfo->ClipMode(TGLSceneInfo::kClipNone);
00270 }
00271
00272 sinfo->ClipPlanes().clear();
00273 return;
00274 }
00275 ++it;
00276 }
00277 sinfo->SetLastClip(ctx.Clip());
00278 sinfo->SetClipStamp(ctx.Clip()->TimeStamp());
00279 }
00280
00281 sinfo->SetLastCamera(ctx.GetCamera());
00282 sinfo->SetCameraStamp(ctx.GetCamera()->TimeStamp());
00283 }
00284
00285
00286 void TGLSceneBase::LodifySceneInfo(TGLRnrCtx& ctx)
00287 {
00288
00289
00290
00291
00292 if (gDebug > 3)
00293 {
00294 Info("TGLSceneBase::LodifySceneInfo",
00295 "'%s' timestamp=%u lod=%d",
00296 GetName(), fTimeStamp, ctx.CombiLOD());
00297 }
00298
00299 TGLSceneInfo & sInfo = * ctx.GetSceneInfo();
00300 sInfo.SetLastLOD(ctx.CombiLOD());
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 void TGLSceneBase::PreDraw(TGLRnrCtx & rnrCtx)
00310 {
00311
00312
00313
00314
00315
00316
00317 if ( ! IsDrawOrSelectLock()) {
00318 Error("TGLSceneBase::FullRender", "expected Draw or Select Lock");
00319 }
00320
00321 TGLSceneInfo& sInfo = * rnrCtx.GetSceneInfo();
00322
00323
00324
00325 if (fTimeStamp > sInfo.SceneStamp())
00326 {
00327 RebuildSceneInfo(rnrCtx);
00328 }
00329
00330
00331 Bool_t needUpdate = sInfo.HasUpdateTimeouted();
00332
00333 if (rnrCtx.GetCamera() != sInfo.LastCamera())
00334 {
00335 sInfo.ResetCameraStamp();
00336 needUpdate = kTRUE;
00337 }
00338 else if (rnrCtx.GetCamera()->TimeStamp() > sInfo.CameraStamp())
00339 {
00340 needUpdate = kTRUE;
00341 }
00342
00343 TGLClip* clip = 0;
00344 if (sInfo.Clip() != 0) clip = sInfo.Clip();
00345 else if (fClip != 0) clip = fClip;
00346 else clip = rnrCtx.ViewerClip();
00347 if (clip != sInfo.LastClip())
00348 {
00349 sInfo.ResetClipStamp();
00350 needUpdate = kTRUE;
00351 }
00352 else if (clip && clip->TimeStamp() > sInfo.ClipStamp())
00353 {
00354 needUpdate = kTRUE;
00355 }
00356 rnrCtx.SetClip(clip);
00357
00358 if (needUpdate)
00359 {
00360 UpdateSceneInfo(rnrCtx);
00361 }
00362
00363
00364
00365 Short_t lod;
00366 if (sInfo.LOD() != TGLRnrCtx::kLODUndef) lod = sInfo.LOD();
00367 else if (fLOD != TGLRnrCtx::kLODUndef) lod = fLOD;
00368 else lod = rnrCtx.ViewerLOD();
00369 rnrCtx.SetSceneLOD(lod);
00370 rnrCtx.SetCombiLOD(TMath::Min(rnrCtx.ViewerLOD(), rnrCtx.SceneLOD()));
00371 if (needUpdate || rnrCtx.CombiLOD() != sInfo.LastLOD())
00372 {
00373 LodifySceneInfo(rnrCtx);
00374 }
00375
00376
00377 Short_t style;
00378 if (sInfo.Style() != TGLRnrCtx::kStyleUndef) style = sInfo.Style();
00379 else if (fStyle != TGLRnrCtx::kStyleUndef) style = fStyle;
00380 else style = rnrCtx.ViewerStyle();
00381 rnrCtx.SetSceneStyle(style);
00382 sInfo.SetLastStyle(style);
00383
00384
00385 Float_t wf_linew;
00386 if (sInfo.WFLineW() != 0) wf_linew = sInfo.WFLineW();
00387 else if (fWFLineW != 0) wf_linew = fWFLineW;
00388 else wf_linew = rnrCtx.ViewerWFLineW();
00389 rnrCtx.SetSceneWFLineW(wf_linew);
00390 sInfo.SetLastWFLineW(wf_linew);
00391
00392 Float_t ol_linew;
00393 if (sInfo.OLLineW() != 0) ol_linew = sInfo.OLLineW();
00394 else if (fOLLineW != 0) ol_linew = fOLLineW;
00395 else ol_linew = rnrCtx.ViewerOLLineW();
00396 rnrCtx.SetSceneOLLineW(ol_linew);
00397 sInfo.SetLastOLLineW(ol_linew);
00398 }
00399
00400
00401 void TGLSceneBase::PreRender(TGLRnrCtx & rnrCtx)
00402 {
00403
00404
00405
00406
00407
00408 TGLSceneInfo& sInfo = * rnrCtx.GetSceneInfo();
00409
00410 rnrCtx.SetClip (sInfo.LastClip());
00411 rnrCtx.SetCombiLOD (sInfo.LastLOD());
00412 rnrCtx.SetSceneStyle (sInfo.LastStyle());
00413 rnrCtx.SetSceneWFLineW (sInfo.LastWFLineW());
00414 rnrCtx.SetSceneOLLineW (sInfo.LastOLLineW());
00415
00416
00417
00418
00419
00420
00421 }
00422
00423
00424 void TGLSceneBase::Render(TGLRnrCtx & rnrCtx)
00425 {
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 RenderOpaque(rnrCtx);
00437 RenderTransp(rnrCtx);
00438 RenderSelOpaque(rnrCtx);
00439 RenderSelTransp(rnrCtx);
00440 }
00441
00442
00443 void TGLSceneBase::RenderOpaque(TGLRnrCtx & )
00444 {
00445
00446 }
00447
00448
00449 void TGLSceneBase::RenderTransp(TGLRnrCtx & )
00450 {
00451
00452 }
00453
00454
00455 void TGLSceneBase::RenderSelOpaque(TGLRnrCtx & )
00456 {
00457
00458 }
00459
00460
00461 void TGLSceneBase::RenderSelTransp(TGLRnrCtx & )
00462 {
00463
00464 }
00465
00466
00467 void TGLSceneBase::PostRender(TGLRnrCtx & )
00468 {
00469
00470
00471
00472
00473
00474
00475 }
00476
00477
00478 void TGLSceneBase::PostDraw(TGLRnrCtx & )
00479 {
00480
00481
00482
00483 }
00484
00485
00486
00487
00488
00489
00490 Bool_t TGLSceneBase::ResolveSelectRecord(TGLSelectRecord & ,
00491 Int_t )
00492 {
00493
00494
00495
00496
00497
00498
00499
00500
00501 return kFALSE;
00502 }