ROOT logo
// $Id: WSTube.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/.

//__________________________________________________________________________
// WSTube
//
//

#include "WSTube.h"
#include "WSTube.c7"
#include <Glasses/WSPoint.h>

#include <Glasses/ZHashList.h>
#include <Glasses/ZQueen.h>
#include <Glasses/Sphere.h>

#include <Gled/GThread.h>

#include <TSystem.h>

ClassImp(WSTube);

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

void WSTube::_init()
{
  mTransSource = TS_Links;

  bWeakConnect = true;
  mDefWidth    = 0.1;
  mDefSpread   = 0.02;
  mDefTension  = 1;

  mVecA.SetX(1);
  mVecB.SetX(1);

  mDefVelocity      = 0.2;
  mMinWaitTime      = 0.05;
  mConnectionStauts = CS_Disconnected;
  m_conn_cof = 0;
}

WSTube::WSTube(const Text_t* n, const Text_t* t) :
  WSSeed(n,t)
{
  _init();
}

WSTube::~WSTube()
{
  delete m_conn_cof;
}

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

void WSTube::define_direction(ZTrans& t, const ZPoint& dr,
			      const TLorentzVector& vec, const TLorentzVector& sgm)
{
  ZPoint x;
  x += t.GetBaseVec(1) * (vec.X() + mRnd.Gaus(0, sgm.X()));
  x += t.GetBaseVec(2) * (vec.Y() + mRnd.Gaus(0, sgm.Y()));
  x += t.GetBaseVec(3) * (vec.Z() + mRnd.Gaus(0, sgm.Z()));
  x += dr              * (vec.T() + mRnd.Gaus(0, sgm.T()));

  t.SetBaseVec(1, x);
  t.OrtoNorm3();
}

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

void WSTube::AdEnlightenment()
{
  PARENT_GLASS::AdEnlightenment();
  mRnd.SetSeed(mSaturnID);
  if(mTravelers == 0) {
    assign_link<ZHashList>(mTravelers, FID(), "DependentLenses");
    mTravelers->SetElementFID(ZNode::FID());
  }
}

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

void WSTube::connect(WSPoint*& ap, WSPoint*& bp)
{
  static const Exc_t _eh("WSTube::connect ");

  TString nameA, nameB;

  switch (mTransSource)
  {
    case TS_Links:
    {
      if(mNodeA == 0 || mNodeB == 0)
        throw(_eh + "node links A and B must be set.");

      ZNode* abcp = ZNode::FindCommonParent(mNodeA.get(), mNodeB.get());
      if(abcp == 0)
        throw(_eh + "nodes A and B have no common parent.");

      ZNode* top  = ZNode::FindCommonParent(this, abcp);
      if(top == 0)
        throw(_eh + "this WSTube does not have a common parent w/ nodes A and B.");


      auto_ptr<ZTrans> at( ZNode::BtoA(this, *mNodeA, top) );
      auto_ptr<ZTrans> bt( ZNode::BtoA(this, *mNodeB, top) );
      at->Unscale(); // Usually helpful; should be an option?
      bt->Unscale();
      mTransA = *at;
      mTransB = *bt;

      nameA = mNodeA->GetName();
      nameB = mNodeB->GetName();

      break;
    }
    case TS_Transes:
    {
      nameA = "<ext-a>";
      nameB = "<ext-b>";

      break;
    }
  }

  // vector A -> B
  ZPoint dr(mTransB.GetPos() - mTransA.GetPos());
  dr.Normalize();

  ap = new WSPoint("TubeStart", GForm("Tube %s->%s", nameA.Data(), nameB.Data()));
  ap->SetTrans(mTransA);
  define_direction(ap->ref_trans(), dr, mVecA, mSgmA);
  ap->SetW(mDefWidth/2);
  ap->SetScale(mDefSpread);
  ap->SetT(mDefTension);

  bp = new WSPoint("TubeEnd", GForm("Tube %s->%s", nameA.Data(), nameB.Data()));
  bp->SetTrans(mTransB);
  define_direction(bp->ref_trans(), dr, mVecB, mSgmB);
  bp->SetW(mDefWidth/2);
  bp->SetScale(-mDefSpread);
  bp->SetT(mDefTension);
}

void WSTube::disconnect()
{
  mTravelers->ClearList();
  m_traveler_list.clear();
  ClearList();
}

void WSTube::assert_disconnect(const Exc_t& eh)
{
  if(mConnectionStauts != CS_Disconnected) {
    if(bWeakConnect) {
      GLensWriteHolder wrlck(this);
      disconnect();
      mConnectionStauts = CS_Disconnected;
    } else {
      throw(eh + "not disconnected.");
    }
  }
}

void WSTube::conn_travel(WSPoint* p, Double_t t)
{
  // Expects t in [0..1]
  // Spread does not work.

  ZTrans& lcf = p->ref_trans();
  const Double_t t2 = t*t, t3 = t2*t;

  Double_t* Pnt = lcf.ArrT();
  Double_t* Axe = lcf.ArrX();

  for(Int_t i=0; i<3; i++) {
    const TMatrixDRow R( (*m_conn_cof)[i] );
    Pnt[i] = R[0] +   R[1]*t +   R[2]*t2 + R[3]*t3;
    Axe[i] = R[1] + 2*R[2]*t + 3*R[3]*t2;
  }
  {
    const TMatrixDRow R( (*m_conn_cof)[3] );
    p->mW = R[0] +   R[1]*t +   R[2]*t2 + R[3]*t3;
  }
  lcf.OrtoNorm3();
}

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

void WSTube::Connect()
{
  static const Exc_t _eh("WSTube::Connect ");

  assert_disconnect(_eh);

  WSPoint *ap, *bp;
  connect(ap, bp);
  // These should be via ZQueen::IncarnateWAttach for cluster stuff.
  { GLensWriteHolder wrlck(this);
    mQueen->CheckIn(ap); Add(ap);
    mQueen->CheckIn(bp); Add(bp);
  }

  mConnectionStauts = CS_Connected;
  mStampReqTring = Stamp(FID());
}

void WSTube::Disconnect()
{
  static const Exc_t _eh("WSTube::Disconnect ");

  if(mConnectionStauts != CS_Connected && !bWeakConnect)
    throw(_eh + "not connected.");

  disconnect();
  mConnectionStauts = CS_Disconnected;
  Stamp(FID());
}

void WSTube::AnimateConnect(Float_t velocity)
{
  static const Exc_t _eh("WSTube::AnimatedConnect ");

  assert_disconnect(_eh);

  WSPoint *ap, *bp;
  connect(ap, bp);
  Bool_t rnrself_state = bRnrSelf;
  bRnrSelf = false;
  // These should be via ZQueen::IncarnateWAttach for cluster stuff.
  { GLensWriteHolder wrlck(this);
    mQueen->CheckIn(ap); Add(ap);
    mQueen->CheckIn(bp); Add(bp);
  }

  ap->Coff(bp);
  m_conn_cof = new TMatrixD(ap->RefCoffs());
  bp->SetTrans(ap->RefTrans());

  if(velocity == 0) velocity = mDefVelocity;
  m_conn_time = 0;
  m_conn_vel  = velocity;

  bRnrSelf = rnrself_state;
  mConnectionStauts = CS_Connecting;
  Stamp(FID());
}

void WSTube::AnimateDisconnect(Float_t velocity, Bool_t delay_p)
{
  // If delay_p==true resend mir to self if connecting.

  static const Exc_t _eh("WSTube::AnimateDisconnect ");

  if(mConnectionStauts == CS_Connecting && delay_p) {
    auto_ptr<ZMIR> redo( S_AnimateDisconnect(velocity, delay_p) );
    GTime time(GTime::I_Now);
    // Don't know anything about time scale ... so take 1 seconf.
    time += 1.0;
    mSaturn->DelayedShootMIR(redo, time);
    return;
  }

  if(mConnectionStauts != CS_Connected)
    throw(_eh + "not connected.");

  WSPoint *ap, *bp;
  connect(ap, bp);
  ap->Coff(bp);
  m_conn_cof = new TMatrixD(m_first_point->RefCoffs());

  if(velocity == 0) velocity = mDefVelocity;
  m_conn_time = Length();
  m_conn_vel  = -velocity;

  mConnectionStauts = CS_Disconnecting;

  Stamp(FID());
}

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

void WSTube::MakeTraveler(Float_t velocity, Float_t wait_time)
{
  static const Exc_t _eh("WSTube::MakeTraveler ");

  if(mConnectionStauts != CS_Connected && mConnectionStauts != CS_Connecting)
    throw(_eh + "not connected or connecting.");

  if(velocity == 0)            velocity  = mDefVelocity;
  if(wait_time < mMinWaitTime) wait_time = mMinWaitTime;

  Float_t len      = Length();
  Float_t init_pos = (velocity > 0) ? 0 : len;

  Sphere* s = new Sphere("Observator");
  TransAtTime(s->ref_trans(), init_pos, true);
  s->SetUseScale(true);
  s->SetSx(2*mDefWidth); s->SetSy(mDefWidth); s->SetSz(mDefWidth);
  s->SetColor(0.2+0.8*mRnd.Rndm(), 0.2+0.8*mRnd.Rndm(), 0.2+0.8*mRnd.Rndm());
  mQueen->CheckIn(s);
  s->SetParent(this);

  list<Traveler>::iterator list_pos = m_traveler_list.end();
  if( ! m_traveler_list.empty()) {
    if(velocity > 0) {
      if(m_traveler_list.front().fPosition < wait_time &&
	 m_traveler_list.front().fVelocity > 0)
	{
	  init_pos = m_traveler_list.front().fPosition - wait_time;
	}
      list_pos = m_traveler_list.begin();
    } else {
      if(m_traveler_list.back().fPosition > len - wait_time &&
	 m_traveler_list.back().fVelocity < 0)
	{
	  init_pos = m_traveler_list.back().fPosition + wait_time;
	}
    }
  }
  m_traveler_list.insert(list_pos, Traveler(s, init_pos , velocity));
}

void WSTube::TimeTick(Double_t t, Double_t dt)
{
  if( mConnectionStauts == CS_Connected ||
     (mConnectionStauts == CS_Disconnecting && ! m_traveler_list.empty())) {

    PARENT_GLASS::TimeTick(t, dt);

    GLensWriteHolder wrlck(this);
    Float_t len = Length();
    list<Traveler>::iterator i = m_traveler_list.begin();
    while(i != m_traveler_list.end()) {
      Float_t step  = i->fVelocity*dt;
      i->fPosition += step;
      if(i->fShown == false && i->fPosition >= 0 && i->fPosition <= len) {
	mTravelers->Add(i->fNode);
	i->fShown = true;
      }
      if((i->fVelocity < 0 && i->fPosition < 0) ||
	 (i->fVelocity > 0 && i->fPosition > len))
	{
	  list<Traveler>::iterator j = i--;
	  mTravelers->RemoveAll(j->fNode);
	  m_traveler_list.erase(j);
	  break;
	}
      {
	GLensWriteHolder node_wrlck(i->fNode);
	TransAtTime(i->fNode->ref_trans(), i->fPosition, false);
	i->fNode->StampReqTrans();
      }
      ++i;
    }

  }
  else if(mConnectionStauts == CS_Connecting ||
	  mConnectionStauts == CS_Disconnecting) {

    GLensWriteHolder wrlck(this);
    Float_t len  = Length();
    Float_t step = m_conn_vel*dt;
    Bool_t done  = false;
    m_conn_time += step;

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