#include "TEveBoxSet.h"
#include "TEveShape.h"
#include "TRandom.h"
ClassImp(TEveBoxSet);
TEveBoxSet::TEveBoxSet(const char* n, const char* t) :
TEveDigitSet (n, t),
fBoxType (kBT_Undef),
fDefWidth (1),
fDefHeight (1),
fDefDepth (1),
fDrawConeCap (kFALSE)
{
fDisableLighting = kFALSE;
}
Int_t TEveBoxSet::SizeofAtom(TEveBoxSet::EBoxType_e bt)
{
static const TEveException eH("TEveBoxSet::SizeofAtom ");
switch (bt) {
case kBT_Undef: return 0;
case kBT_FreeBox: return sizeof(BFreeBox_t);
case kBT_AABox: return sizeof(BAABox_t);
case kBT_AABoxFixedDim: return sizeof(BAABoxFixedDim_t);
case kBT_Cone: return sizeof(BCone_t);
case kBT_EllipticCone: return sizeof(BEllipticCone_t);
default: throw(eH + "unexpected atom type.");
}
return 0;
}
void TEveBoxSet::Reset(TEveBoxSet::EBoxType_e boxType, Bool_t valIsCol, Int_t chunkSize)
{
fBoxType = boxType;
fValueIsColor = valIsCol;
fDefaultValue = valIsCol ? 0 : kMinInt;
if (fOwnIds)
ReleaseIds();
fPlex.Reset(SizeofAtom(fBoxType), chunkSize);
}
void TEveBoxSet::Reset()
{
if (fOwnIds)
ReleaseIds();
fPlex.Reset(SizeofAtom(fBoxType), TMath::Max(fPlex.N(), 64));
}
void TEveBoxSet::AddBox(const Float_t* verts)
{
static const TEveException eH("TEveBoxSet::AddBox ");
if (fBoxType != kBT_FreeBox)
throw(eH + "expect free box-type.");
BFreeBox_t* b = (BFreeBox_t*) NewDigit();
memcpy(b->fVertices, verts, sizeof(b->fVertices));
TEveShape::CheckAndFixBoxOrientationFv(b->fVertices);
}
void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d)
{
static const TEveException eH("TEveBoxSet::AddBox ");
if (fBoxType != kBT_AABox)
throw(eH + "expect axis-aligned box-type.");
BAABox_t* box = (BAABox_t*) NewDigit();
box->fA = a; box->fB = b; box->fC = c;
box->fW = w; box->fH = h; box->fD = d;
}
void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c)
{
static const TEveException eH("TEveBoxSet::AddBox ");
if (fBoxType != kBT_AABoxFixedDim)
throw(eH + "expect axis-aligned fixed-dimension box-type.");
BAABoxFixedDim_t* box = (BAABoxFixedDim_t*) NewDigit();
box->fA = a; box->fB = b; box->fC = c;
}
void TEveBoxSet::AddCone(const TEveVector& pos, const TEveVector& dir, Float_t r)
{
static const TEveException eH("TEveBoxSet::AddCone ");
if (fBoxType != kBT_Cone)
throw(eH + "expect cone box-type.");
BCone_t* cone = (BCone_t*) NewDigit();
cone->fPos = pos;
cone->fDir = dir;
cone->fR = r;
}
void TEveBoxSet::AddEllipticCone(const TEveVector& pos, const TEveVector& dir,
Float_t r, Float_t r2, Float_t angle)
{
static const TEveException eH("TEveBoxSet::AddEllipticCone ");
if (fBoxType != kBT_EllipticCone)
throw(eH + "expect ellicptic-cone box-type.");
BEllipticCone_t* cone = (BEllipticCone_t*) NewDigit();
cone->fPos = pos;
cone->fDir = dir;
cone->fR = r;
cone->fR2 = r2;
cone->fAngle = angle;
}
void TEveBoxSet::ComputeBBox()
{
static const TEveException eH("TEveBoxSet::ComputeBBox ");
if (fFrame != 0)
{
BBoxInit();
Int_t n = fFrame->GetFrameSize() / 3;
Float_t *bbps = fFrame->GetFramePoints();
for (int i=0; i<n; ++i, bbps+=3)
BBoxCheckPoint(bbps);
return;
}
if(fPlex.Size() == 0)
{
BBoxZero();
return;
}
BBoxInit();
TEveChunkManager::iterator bi(fPlex);
switch (fBoxType)
{
case kBT_FreeBox:
{
while (bi.next()) {
BFreeBox_t& b = * (BFreeBox_t*) bi();
for (Int_t i = 0; i < 8; ++i)
BBoxCheckPoint(b.fVertices[i]);
}
break;
}
case kBT_AABox:
{
while (bi.next()) {
BAABox_t& b = * (BAABox_t*) bi();
BBoxCheckPoint(b.fA, b.fB, b.fC);
BBoxCheckPoint(b.fA + b.fW, b.fB + b.fH , b.fC + b.fD);
}
break;
}
case kBT_AABoxFixedDim:
{
while (bi.next()) {
BAABoxFixedDim_t& b = * (BAABoxFixedDim_t*) bi();
BBoxCheckPoint(b.fA, b.fB, b.fC);
BBoxCheckPoint(b.fA + fDefWidth, b.fB + fDefHeight , b.fC + fDefDepth);
}
break;
}
case kBT_Cone:
{
Float_t mag2=0, mag2Max=0, rMax=0;
while (bi.next()) {
BCone_t& b = * (BCone_t*) bi();
BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
mag2 = b.fDir.Mag2();
if (mag2>mag2Max) mag2Max=mag2;
if (b.fR>rMax) rMax=b.fR;
}
Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
break;
}
case kBT_EllipticCone:
{
Float_t mag2=0, mag2Max=0, rMax=0;
while (bi.next()) {
BEllipticCone_t& b = * (BEllipticCone_t*) bi();
BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
mag2 = b.fDir.Mag2();
if (mag2>mag2Max) mag2Max=mag2;
if (b.fR > rMax) rMax = b.fR;
if (b.fR2 > rMax) rMax = b.fR2;
}
Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
break;
}
default:
{
throw(eH + "unsupported box-type.");
}
}
}
void TEveBoxSet::Test(Int_t nboxes)
{
Reset(kBT_AABox, kTRUE, nboxes);
TRandom rnd(0);
const Float_t origin = 10, size = 2;
Int_t color;
for(Int_t i=0; i<nboxes; ++i)
{
AddBox(origin * rnd.Uniform(-1, 1),
origin * rnd.Uniform(-1, 1),
origin * rnd.Uniform(-1, 1),
size * rnd.Uniform(0.1, 1),
size * rnd.Uniform(0.1, 1),
size * rnd.Uniform(0.1, 1));
TEveUtil::ColorFromIdx(rnd.Integer(256), (UChar_t*)&color);
DigitValue(color);
}
}