ROOT logo
// $Id: Amphitheatre.cxx 2597 2011-11-13 08:03:06Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

//__________________________________________________________________________
// Amphitheatre
//
//

#include "Amphitheatre.h"
#include "Amphitheatre.c7"
#include <Glasses/ZQueen.h>
#include <Glasses/Sphere.h>

#include <TMath.h>

ClassImp(Amphitheatre);

/**************************************************************************/

void Amphitheatre::_init()
{
  mNewGuests = 0;

  mNumCh = mNumChFree = 0;

  mStageSides = 7; mStageRot  = 0;
  mStageSize  = 1; mChairSize = 0.15;

  mGuestSize     = 0.2;
  mGuestScaleFac = 0.01;

  mRepX0 = 2*mChairSize;
  mRepXm = 0.5*mGuestSize;
  mRepXM = 5*mGuestSize;

  mGuestStep    = 1;
  mStepSleepMS  = 100;
  bChairHunt    = false; // This is state, true if hunt is underway.
  bInnerHunt    = true;  // True: use internal MIR-callback for hunt.

  bRnrStage  = true; bRnrChairs = true;
  // Stage col white.
  mChairCol.rgba(0.6, 0.9, 0.6);

  mRnd.SetSeed(0); // !! This NOT distributed.
}

/**************************************************************************/

void Amphitheatre::AdEnlightenment()
{
  PARENT_GLASS::AdEnlightenment();
  if(mNewGuests == 0) {
    assign_link<ZList>(mNewGuests, FID(), "GuestList", GForm("Newly arrived guests of %s", GetName()));
    mNewGuests->SetElementFID(ZNode::FID());
    mNewGuests->SetMIRActive(false);
  }
}

/**************************************************************************/

void Amphitheatre::CreateChairs(Float_t radius, Float_t xoffset, Float_t z,
				Float_t dphi_deg, Int_t nchair)
{
  Float_t dphi = dphi_deg * TMath::DegToRad();
  Float_t step = dphi / (nchair - 1);
  Float_t phi0 = -dphi / 2;
  for (int i=0; i<nchair; ++i)
  {
    Float_t p = phi0 + i*step;
    ZPoint pos(radius*TMath::Cos(p), radius*TMath::Sin(p), z);
    pos[0] += xoffset;
    mChairs.push_back(Chair(pos));
  }
  mNumCh += nchair; mNumChFree += nchair;
  Stamp(FID());
}


void Amphitheatre::RemoveChairs()
{
  mChairs.clear();
  mNumCh = mNumChFree = 0;
  Stamp(FID());
}

/**************************************************************************/

void Amphitheatre::AddGuest(ZNode* guest)
{
  mNewGuests->Add(guest);
  guest->WriteLock();
  ZNode* gp = guest->GetParent();
  if(gp != this) {
    if(gp != 0) {
      auto_ptr<ZTrans> t( ZNode::BtoA(this, guest) );
      if(t.get() != 0) {
	Double_t s[3];
	t->Unscale(s[0], s[1], s[2]);
	guest->SetTrans(*t);
	guest->SetScales(s[0], s[1], s[2]);
      }
    }
    guest->SetParent(this);
    Add(guest);
  }
  guest->WriteUnlock();
}

void Amphitheatre::ClearFailedGuests()
{
  mNewGuests->WriteLock();
  lpZGlass_t l; mNewGuests->CopyList(l);
  for(lpZGlass_i i=l.begin(); i!=l.end(); ++i)
    RemoveAll(*i);
  mNewGuests->ClearList();
  mNewGuests->WriteUnlock();
}

void Amphitheatre::ClearAmphitheatre()
{
  ClearFailedGuests();
  ClearList();
  for(lChair_i c=mChairs.begin(); c!=mChairs.end(); ++c) c->fNode = 0;
  mNumChFree = mNumCh;
  Stamp(FID());
}

/**************************************************************************/
/**************************************************************************/

Amphitheatre::Chair* Amphitheatre::closest_free_chair(const ZPoint& pos)
{
  if (mNumChFree <= 0)
    return 0;

  Double_t min_r2 = 1e9;
  lChair_i min_ch;
  for (lChair_i i = mChairs.begin(); i != mChairs.end(); ++i)
  {
    if (i->freep())
    {
      ZPoint dr(i->fPos - pos);
      Double_t r2 = dr.Mag2();
      if (r2 < min_r2)
      {
	min_r2 = r2;
	min_ch = i;
      }
    }
  }
  return &(*min_ch);
}

/**************************************************************************/

void Amphitheatre::chair_hunt(Double_t t, Double_t dt)
{
  if(bChairHunt == false)
    return;

  Bool_t changep = false;

  typedef list<ZNode*>		 lpZNode_t;
  typedef list<ZNode*>::iterator lpZNode_i;

  lpZNode_t nodes;
  mNewGuests->CopyListByGlass<ZNode>(nodes);

  if(nodes.empty() || mNumChFree <= 0) {
    StopHunt();
    return;
  }

  Double_t max_step = mGuestStep*dt;

  for (lpZNode_i n=nodes.begin(); n!=nodes.end(); ++n)
  {
    ZNode* node = *n;
    if(mNumChFree <= 0)
      break;

    ZPoint x     = node->RefTrans().GetPos();
    Chair* chair = closest_free_chair(x);

    x = chair->fPos - x;
    Double_t dx = x.Mag();
    if(dx > max_step) {
      x *= (max_step/dx);
    }
    // printf("Got r = %f, %f, %f; %f\n", f.x(), f.y(), f.z(), f.Mag());

    bool finalp = (dx <= max_step); // Guest has reached the chair.

    node->WriteLock();
    node->Move3PF(x.x, x.y, x.z);
    fix_guest_scale(node, finalp);
    // !! Could rotate it along travel axis.
    node->WriteUnlock();

    if(finalp) {
      changep = true;
      // !!! Should also rotate it towards the stage.
      mNewGuests->WriteLock();
      mNewGuests->RemoveAll(node);
      mNewGuests->WriteUnlock();
      chair->fNode = node;
      --mNumChFree;
      lpZNode_i to_remove = n--;
      nodes.erase(to_remove);
    }
  }

  // Spread the remaining roamers if too close.
  const Double_t rxm = mRepX0*mRepXm;
  const Double_t rxM = mRepX0*mRepXM;

  for (lpZNode_i n=nodes.begin(); n!=nodes.end(); ++n)
  {
    ZPoint f;
    ZNode* node = *n;
    ZPoint x(node->RefTrans().GetPos());
    // loop over rivals
    for (lpZNode_i o=nodes.begin(); o!=nodes.end(); ++o)
    {
      if(o == n) continue;
      ZPoint y = (*o)->RefTrans().GetPos();
      y -= x;
      Double_t d = y.Mag();
      if (d < rxM)
      {
	if (d < rxm) { y *= rxm/d; d = rxm; }
	y *= mRepX0*(1/d - 1/rxm)/d;
	f += y;
      }
    }
    // loop over taken chairs
    for (lChair_i i=mChairs.begin(); i != mChairs.end(); ++i)
    {
      if (! i->freep())
      {
	ZPoint y = i->fNode->RefTrans().GetPos();
	y -= x;
	Double_t d = y.Mag();
	if (d < rxM)
	{
	  if(d < rxm) { y *= rxm/d; d = rxm; }
	  y *= mRepX0*(1/d - 1/rxm)/d;
	  f += y;
	}
      }
    }

    Double_t fmag = f.Mag();
    if (fmag != 0)
    {
      if(fmag > max_step/2) f *= max_step/2/fmag;
      node->WriteLock();
      node->Move3LF(f.x, f.y, f.z);
      node->WriteUnlock();
    }
  }

  if(changep)
    Stamp(FID());

  if(bInnerHunt)
    chair_hunt_emit_mir(t+dt, dt);
}

void Amphitheatre::chair_hunt_emit_mir(Double_t t, Double_t dt)
{
  GTime at(GTime::I_Now); at += dt;
  auto_ptr<ZMIR> mir( S_chair_hunt(t, dt) );
  mSaturn->DelayedShootMIR(mir, at);
}

/**************************************************************************/

void Amphitheatre::fix_guest_scale(ZNode* guest, bool finalp)
{
  Float_t s[3];
  s[0] = guest->GetSx(); s[1] = guest->GetSy(); s[2] = guest->GetSz();
  Float_t avgs = (s[0]+s[1]+s[2])/3;
  Float_t ds = mGuestSize - avgs;
  // printf("%-10s %8f %8f\n", guest->GetName(), avgs, ds);
  if(TMath::Abs(ds) > 0.05 || finalp) {
    if(!finalp) ds *= mGuestScaleFac; // exponential approach
    guest->SetSx(s[0]*(1 + ds/s[0]));
    guest->SetSy(s[1]*(1 + ds/s[1]));
    guest->SetSz(s[2]*(1 + ds/s[2]));
  }
}

/**************************************************************************/

void Amphitheatre::StartHunt()
{
  if(bChairHunt)
    return;
  bChairHunt = true;
  if(bInnerHunt)
    chair_hunt_emit_mir(0, mStepSleepMS/1000.0);
  Stamp(FID());
}

void Amphitheatre::StopHunt()
{
  if(!bChairHunt) return;
  bChairHunt = false;
  Stamp(FID());
}

void Amphitheatre::TimeTick(Double_t t, Double_t dt)
{
  if(!bChairHunt || bInnerHunt) return;
  chair_hunt(t, dt);
}

/**************************************************************************/


inline
Double_t Amphitheatre::rnd(Double_t k, Double_t n)
{
  return k*mRnd.Rndm() + n;
}

void Amphitheatre::MakeRandomGuests(Int_t nguests, Float_t box_size)
{
  // This is for testing only; NOT DISTRIBUTED.

  Float_t bh = box_size / 2;
  for(Int_t i=0; i<nguests; ++i) {
    Sphere* s = new Sphere(GForm("Guest %d", int(1000*mRnd.Rndm())));

    s->SetPos(rnd(box_size, -bh), rnd(box_size, -bh), rnd(box_size, -bh));
    s->SetColor(rnd(0.6,0.4), rnd(0.6,0.4), rnd(0.6,0.4));
    s->SetLOD(12);
    s->SetRadius(0.1);
    mQueen->CheckIn(s);
    Add(s);
    mNewGuests->WriteLock();
    mNewGuests->Add(s);
    mNewGuests->WriteUnlock();
  }
}
 Amphitheatre.cxx:1
 Amphitheatre.cxx:2
 Amphitheatre.cxx:3
 Amphitheatre.cxx:4
 Amphitheatre.cxx:5
 Amphitheatre.cxx:6
 Amphitheatre.cxx:7
 Amphitheatre.cxx:8
 Amphitheatre.cxx:9
 Amphitheatre.cxx:10
 Amphitheatre.cxx:11
 Amphitheatre.cxx:12
 Amphitheatre.cxx:13
 Amphitheatre.cxx:14
 Amphitheatre.cxx:15
 Amphitheatre.cxx:16
 Amphitheatre.cxx:17
 Amphitheatre.cxx:18
 Amphitheatre.cxx:19
 Amphitheatre.cxx:20
 Amphitheatre.cxx:21
 Amphitheatre.cxx:22
 Amphitheatre.cxx:23
 Amphitheatre.cxx:24
 Amphitheatre.cxx:25
 Amphitheatre.cxx:26
 Amphitheatre.cxx:27
 Amphitheatre.cxx:28
 Amphitheatre.cxx:29
 Amphitheatre.cxx:30
 Amphitheatre.cxx:31
 Amphitheatre.cxx:32
 Amphitheatre.cxx:33
 Amphitheatre.cxx:34
 Amphitheatre.cxx:35
 Amphitheatre.cxx:36
 Amphitheatre.cxx:37
 Amphitheatre.cxx:38
 Amphitheatre.cxx:39
 Amphitheatre.cxx:40
 Amphitheatre.cxx:41
 Amphitheatre.cxx:42
 Amphitheatre.cxx:43
 Amphitheatre.cxx:44
 Amphitheatre.cxx:45
 Amphitheatre.cxx:46
 Amphitheatre.cxx:47
 Amphitheatre.cxx:48
 Amphitheatre.cxx:49
 Amphitheatre.cxx:50
 Amphitheatre.cxx:51
 Amphitheatre.cxx:52
 Amphitheatre.cxx:53
 Amphitheatre.cxx:54
 Amphitheatre.cxx:55
 Amphitheatre.cxx:56
 Amphitheatre.cxx:57
 Amphitheatre.cxx:58
 Amphitheatre.cxx:59
 Amphitheatre.cxx:60
 Amphitheatre.cxx:61
 Amphitheatre.cxx:62
 Amphitheatre.cxx:63
 Amphitheatre.cxx:64
 Amphitheatre.cxx:65
 Amphitheatre.cxx:66
 Amphitheatre.cxx:67
 Amphitheatre.cxx:68
 Amphitheatre.cxx:69
 Amphitheatre.cxx:70
 Amphitheatre.cxx:71
 Amphitheatre.cxx:72
 Amphitheatre.cxx:73
 Amphitheatre.cxx:74
 Amphitheatre.cxx:75
 Amphitheatre.cxx:76
 Amphitheatre.cxx:77
 Amphitheatre.cxx:78
 Amphitheatre.cxx:79
 Amphitheatre.cxx:80
 Amphitheatre.cxx:81
 Amphitheatre.cxx:82
 Amphitheatre.cxx:83
 Amphitheatre.cxx:84
 Amphitheatre.cxx:85
 Amphitheatre.cxx:86
 Amphitheatre.cxx:87
 Amphitheatre.cxx:88
 Amphitheatre.cxx:89
 Amphitheatre.cxx:90
 Amphitheatre.cxx:91
 Amphitheatre.cxx:92
 Amphitheatre.cxx:93
 Amphitheatre.cxx:94
 Amphitheatre.cxx:95
 Amphitheatre.cxx:96
 Amphitheatre.cxx:97
 Amphitheatre.cxx:98
 Amphitheatre.cxx:99
 Amphitheatre.cxx:100
 Amphitheatre.cxx:101
 Amphitheatre.cxx:102
 Amphitheatre.cxx:103
 Amphitheatre.cxx:104
 Amphitheatre.cxx:105
 Amphitheatre.cxx:106
 Amphitheatre.cxx:107
 Amphitheatre.cxx:108
 Amphitheatre.cxx:109
 Amphitheatre.cxx:110
 Amphitheatre.cxx:111
 Amphitheatre.cxx:112
 Amphitheatre.cxx:113
 Amphitheatre.cxx:114
 Amphitheatre.cxx:115
 Amphitheatre.cxx:116
 Amphitheatre.cxx:117
 Amphitheatre.cxx:118
 Amphitheatre.cxx:119
 Amphitheatre.cxx:120
 Amphitheatre.cxx:121
 Amphitheatre.cxx:122
 Amphitheatre.cxx:123
 Amphitheatre.cxx:124
 Amphitheatre.cxx:125
 Amphitheatre.cxx:126
 Amphitheatre.cxx:127
 Amphitheatre.cxx:128
 Amphitheatre.cxx:129
 Amphitheatre.cxx:130
 Amphitheatre.cxx:131
 Amphitheatre.cxx:132
 Amphitheatre.cxx:133
 Amphitheatre.cxx:134
 Amphitheatre.cxx:135
 Amphitheatre.cxx:136
 Amphitheatre.cxx:137
 Amphitheatre.cxx:138
 Amphitheatre.cxx:139
 Amphitheatre.cxx:140
 Amphitheatre.cxx:141
 Amphitheatre.cxx:142
 Amphitheatre.cxx:143
 Amphitheatre.cxx:144
 Amphitheatre.cxx:145
 Amphitheatre.cxx:146
 Amphitheatre.cxx:147
 Amphitheatre.cxx:148
 Amphitheatre.cxx:149
 Amphitheatre.cxx:150
 Amphitheatre.cxx:151
 Amphitheatre.cxx:152
 Amphitheatre.cxx:153
 Amphitheatre.cxx:154
 Amphitheatre.cxx:155
 Amphitheatre.cxx:156
 Amphitheatre.cxx:157
 Amphitheatre.cxx:158
 Amphitheatre.cxx:159
 Amphitheatre.cxx:160
 Amphitheatre.cxx:161
 Amphitheatre.cxx:162
 Amphitheatre.cxx:163
 Amphitheatre.cxx:164
 Amphitheatre.cxx:165
 Amphitheatre.cxx:166
 Amphitheatre.cxx:167
 Amphitheatre.cxx:168
 Amphitheatre.cxx:169
 Amphitheatre.cxx:170
 Amphitheatre.cxx:171
 Amphitheatre.cxx:172
 Amphitheatre.cxx:173
 Amphitheatre.cxx:174
 Amphitheatre.cxx:175
 Amphitheatre.cxx:176
 Amphitheatre.cxx:177
 Amphitheatre.cxx:178
 Amphitheatre.cxx:179
 Amphitheatre.cxx:180
 Amphitheatre.cxx:181
 Amphitheatre.cxx:182
 Amphitheatre.cxx:183
 Amphitheatre.cxx:184
 Amphitheatre.cxx:185
 Amphitheatre.cxx:186
 Amphitheatre.cxx:187
 Amphitheatre.cxx:188
 Amphitheatre.cxx:189
 Amphitheatre.cxx:190
 Amphitheatre.cxx:191
 Amphitheatre.cxx:192
 Amphitheatre.cxx:193
 Amphitheatre.cxx:194
 Amphitheatre.cxx:195
 Amphitheatre.cxx:196
 Amphitheatre.cxx:197
 Amphitheatre.cxx:198
 Amphitheatre.cxx:199
 Amphitheatre.cxx:200
 Amphitheatre.cxx:201
 Amphitheatre.cxx:202
 Amphitheatre.cxx:203
 Amphitheatre.cxx:204
 Amphitheatre.cxx:205
 Amphitheatre.cxx:206
 Amphitheatre.cxx:207
 Amphitheatre.cxx:208
 Amphitheatre.cxx:209
 Amphitheatre.cxx:210
 Amphitheatre.cxx:211
 Amphitheatre.cxx:212
 Amphitheatre.cxx:213
 Amphitheatre.cxx:214
 Amphitheatre.cxx:215
 Amphitheatre.cxx:216
 Amphitheatre.cxx:217
 Amphitheatre.cxx:218
 Amphitheatre.cxx:219
 Amphitheatre.cxx:220
 Amphitheatre.cxx:221
 Amphitheatre.cxx:222
 Amphitheatre.cxx:223
 Amphitheatre.cxx:224
 Amphitheatre.cxx:225
 Amphitheatre.cxx:226
 Amphitheatre.cxx:227
 Amphitheatre.cxx:228
 Amphitheatre.cxx:229
 Amphitheatre.cxx:230
 Amphitheatre.cxx:231
 Amphitheatre.cxx:232
 Amphitheatre.cxx:233
 Amphitheatre.cxx:234
 Amphitheatre.cxx:235
 Amphitheatre.cxx:236
 Amphitheatre.cxx:237
 Amphitheatre.cxx:238
 Amphitheatre.cxx:239
 Amphitheatre.cxx:240
 Amphitheatre.cxx:241
 Amphitheatre.cxx:242
 Amphitheatre.cxx:243
 Amphitheatre.cxx:244
 Amphitheatre.cxx:245
 Amphitheatre.cxx:246
 Amphitheatre.cxx:247
 Amphitheatre.cxx:248
 Amphitheatre.cxx:249
 Amphitheatre.cxx:250
 Amphitheatre.cxx:251
 Amphitheatre.cxx:252
 Amphitheatre.cxx:253
 Amphitheatre.cxx:254
 Amphitheatre.cxx:255
 Amphitheatre.cxx:256
 Amphitheatre.cxx:257
 Amphitheatre.cxx:258
 Amphitheatre.cxx:259
 Amphitheatre.cxx:260
 Amphitheatre.cxx:261
 Amphitheatre.cxx:262
 Amphitheatre.cxx:263
 Amphitheatre.cxx:264
 Amphitheatre.cxx:265
 Amphitheatre.cxx:266
 Amphitheatre.cxx:267
 Amphitheatre.cxx:268
 Amphitheatre.cxx:269
 Amphitheatre.cxx:270
 Amphitheatre.cxx:271
 Amphitheatre.cxx:272
 Amphitheatre.cxx:273
 Amphitheatre.cxx:274
 Amphitheatre.cxx:275
 Amphitheatre.cxx:276
 Amphitheatre.cxx:277
 Amphitheatre.cxx:278
 Amphitheatre.cxx:279
 Amphitheatre.cxx:280
 Amphitheatre.cxx:281
 Amphitheatre.cxx:282
 Amphitheatre.cxx:283
 Amphitheatre.cxx:284
 Amphitheatre.cxx:285
 Amphitheatre.cxx:286
 Amphitheatre.cxx:287
 Amphitheatre.cxx:288
 Amphitheatre.cxx:289
 Amphitheatre.cxx:290
 Amphitheatre.cxx:291
 Amphitheatre.cxx:292
 Amphitheatre.cxx:293
 Amphitheatre.cxx:294
 Amphitheatre.cxx:295
 Amphitheatre.cxx:296
 Amphitheatre.cxx:297
 Amphitheatre.cxx:298
 Amphitheatre.cxx:299
 Amphitheatre.cxx:300
 Amphitheatre.cxx:301
 Amphitheatre.cxx:302
 Amphitheatre.cxx:303
 Amphitheatre.cxx:304
 Amphitheatre.cxx:305
 Amphitheatre.cxx:306
 Amphitheatre.cxx:307
 Amphitheatre.cxx:308
 Amphitheatre.cxx:309
 Amphitheatre.cxx:310
 Amphitheatre.cxx:311
 Amphitheatre.cxx:312
 Amphitheatre.cxx:313
 Amphitheatre.cxx:314
 Amphitheatre.cxx:315
 Amphitheatre.cxx:316
 Amphitheatre.cxx:317
 Amphitheatre.cxx:318
 Amphitheatre.cxx:319
 Amphitheatre.cxx:320
 Amphitheatre.cxx:321
 Amphitheatre.cxx:322
 Amphitheatre.cxx:323
 Amphitheatre.cxx:324
 Amphitheatre.cxx:325
 Amphitheatre.cxx:326
 Amphitheatre.cxx:327
 Amphitheatre.cxx:328
 Amphitheatre.cxx:329
 Amphitheatre.cxx:330
 Amphitheatre.cxx:331
 Amphitheatre.cxx:332
 Amphitheatre.cxx:333
 Amphitheatre.cxx:334
 Amphitheatre.cxx:335
 Amphitheatre.cxx:336
 Amphitheatre.cxx:337
 Amphitheatre.cxx:338
 Amphitheatre.cxx:339
 Amphitheatre.cxx:340
 Amphitheatre.cxx:341
 Amphitheatre.cxx:342
 Amphitheatre.cxx:343
 Amphitheatre.cxx:344
 Amphitheatre.cxx:345
 Amphitheatre.cxx:346
 Amphitheatre.cxx:347
 Amphitheatre.cxx:348
 Amphitheatre.cxx:349
 Amphitheatre.cxx:350