ROOT logo
// $Id: Crawler.cxx 2342 2010-01-24 20:10:41Z 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/.

#include "Crawler.h"
#include "Crawler.c7"

#include "Tringula.h"
#include "ParaSurf.h"

// Crawler

//______________________________________________________________________________
//
//

ClassImp(Crawler);

//==============================================================================

void Crawler::_init()
{
  mDriveMode = DM_ConstVelocities;

  mLevH = 0.1f;

  mRayOffset = 0;

  mThrottle.SetMinMaxDelta(-1, 4, 1, 1.5);
  mThrottle.SetStdDesireDelta(2);

  mWheel.SetMinMaxDelta(-1, 1, 0.5, 1);
  mWheel.SetStdDesireDelta(1);

  const Float_t turret_speed = 0.15f;
  mLaserUpDn.SetMinMaxDelta(-0.35, 0.7, turret_speed, turret_speed);
  mLaserUpDn.SetStdDesireDelta(2.0f*turret_speed);

  mLaserLtRt.SetMinMaxDelta(-1.0, 1.0, turret_speed,turret_speed);
  mLaserLtRt.SetStdDesireDelta(2.0f*turret_speed);

  mLaserCharge.SetMinMax(0, 60);

  mLaserLen = 0;
}

Crawler::Crawler(const Text_t* n, const Text_t* t) :
  Dynamico(n, t)
{
  _init();
}

Crawler::~Crawler()
{}

//==============================================================================

void Crawler::SetTringula(Tringula* tring)
{
  // Set tringula to which the extendio is attached.
  // Sub-classes override this to reinitialize cached data.

  PARENT_GLASS::SetTringula(tring);

  mRayOffset = 2.0f * mTringula->GetMesh()->GetTTvor()->mMaxEdgeLen;

  // Set laser start -- this should *really* come from outside.
  // Anyway, the whole laser should migrate into something like:
  // class Laser : public Weapon {};
  if (*mMesh)
  {
    const Float_t* mmbb = mMesh->GetTTvor()->mMinMaxBox;
    mLaserBeg.Set(0, 0, mmbb[5]);
    mLaserLen = 0.75f * mmbb[3];
  }
}

//==============================================================================

void Crawler::TimeTick(Double_t t, Double_t dt)
{
  static const Exc_t _eh("Crawler::TimeTick ");

  const Float_t dtf = dt;

  // Controllers
  mThrottle. TimeTick(dtf);
  mWheel.    TimeTick(dtf);
  mLaserUpDn.TimeTick(dtf);
  mLaserLtRt.TimeTick(dtf);

  mLaserCharge.Delta(100.0f*dtf);

  switch (mDriveMode)
  {
    case DM_Parked:
      mVVec.Set(0,0,0);
      break;

    case DM_ConstVelocities:
      break;

    case DM_Controllers:
      // This is uber fake ... just to get stuff connected.
      mVVec.Set(mThrottle.Get(), 0, 0);
      mWVec.Set(mWheel.Get(), 0, 0);
      break;
  }

  using namespace Opcode;

  RayCollider    RC;
  RC.SetTemporalCoherence(true);
  RC.SetClosestHit(true);
  CollisionFaces CF;
  RC.SetDestination(&CF);

  Opcode::Point velocity; // Velocity in master frame.
  Float_t       velocity_mag2, velocity_mag, step_length;

  mTrans.RotateVec3(mVVec, velocity);
  velocity_mag2 = velocity.SquareMagnitude();
  velocity_mag  = sqrtf(velocity_mag2);

  step_length   = velocity_mag * dtf + mExtraStep;
  mExtraStep    = 0;

  if (mDriveMode == DM_Controllers)
  {
    // !!!! The factor 2 below should really be inertia tensor dependant and the force
    // should be calculated and go into mWVec ... or sth.
    Float_t dp;
    dp = mTerrainUp.Dot(mTrans.PtrBaseVecX());
    if (fabsf(dp) > 0.001f)
      mTrans.RotateLF(1, 3, 2.0f*dtf*(acosf(dp) - HALFPI));
    dp = mTerrainUp.Dot(mTrans.PtrBaseVecY());
    if (fabsf(dp) > 0.001f)
      mTrans.RotateLF(2, 3, 2.0f*dtf*(acosf(dp) - HALFPI));
  }

  // Use velocity - is needed afterwards, too.
  // [But can be changed by CheckBoundaries()!]
  // mTrans.Move3LF(mVVec.x * dtf, mVVec.y * dtf, mVVec.z * dtf);
  mTrans.Move3PF(velocity.x * dtf, velocity.y * dtf, velocity.z * dtf);

  mTrans.RotateLF(1, 2, dtf*mWVec.x);
  mTrans.RotateLF(2, 3, dtf*mWVec.y);
  mTrans.RotateLF(3, 1, dtf*mWVec.z);

  mSafety -= step_length;
  if (mSafety < 0)
  {
    // Check boundaries - this can result in tringula switch.
    Bool_t trans_changed = mTringula->CheckBoundaries(this, mSafety);

    if (trans_changed)
    {
      // Recalculate velocity
      mTrans.RotateVec3(mVVec, velocity);
      velocity_mag2 = velocity.SquareMagnitude();
      velocity_mag  = sqrtf(velocity_mag2);

      // Invalidate position dependant caches.
      // GravData should be fine as it is supposedly smooth.
      // Terrain safety ok, too, we should check neighbouring meshes
      // when calculating it.
    }
  }

  Opcode::Point& pos = * (Opcode::Point*) ref_trans().ArrT();

  if (mGrav.DecaySafeties(dtf, step_length))
  {
    mTringula->GetParaSurf()->pos2grav(pos, mGrav);

    Float_t vl = mGrav.Dir() | velocity;  if (vl < 0) vl = -vl;
    Float_t vt = sqrtf(velocity_mag2 - vl*vl);

    update_grav_safeties(vl, vt);

    // Testing printout.
    if (mDebugBits & DB_GravData)
    {
      mGrav.Print();
      printf("  v_mag=%f, vl=%f, vt=%f, t_safe=%f, d_safe=%f (d/v)=%f\n",
             velocity_mag, vl, vt,  mGrav.fSafeTime, mGrav.fSafeDistance,
             mGrav.fSafeDistance / velocity_mag);
    }
  }

  Opcode::Ray R;
  R.mDir  = mGrav.Dir();
  Int_t reoffset_count = 0;
reoffset:
  R.mOrig.Msc(pos, R.mDir, mRayOffset);

  TriMesh* terrain_mesh = mTringula->GetMesh();

  UInt_t cache = mOPCRCCache;
  if (RC.Collide(R, *terrain_mesh->GetOPCModel(), 0, &mOPCRCCache))
  {
    if (CF.GetNbFaces() == 1)
    {
      const CollisionFace& cf = CF.GetFaces()[0];
      pos.TMac(R.mDir, cf.mDistance - mRayOffset - mLevH);

      if (cache != mOPCRCCache)
      {
        mTerrainUp.Set(terrain_mesh->GetTTvor()->TriangleNormal(mOPCRCCache));
	if (mDriveMode != DM_Controllers)
	{
	  mTrans.SetBaseVec(3, mTerrainUp);
	  mTrans.OrtoNorm3Column(2, 3);
	  mTrans.SetBaseVecViaCross(1);
	}
      }
    }
    else
    {
      if (mTringula->GetParaSurf()->IsValidPos(pos))
      {
	if (reoffset_count < 5)
	{
	  ISmess(_eh + RC.CollideInfo(true, R) + GForm(" Increasing ray-offset from %f for '%s'.", mRayOffset, GetName()));
	  mRayOffset *= 2;
	  ++reoffset_count;
	  goto reoffset;
	}
	else
	{
	  // This probably means Crawler has fallen off but opcode
	  // and parasurf perceive this somewhat differently.
	  // This happens in tringula test case (tringula.C(99)).
	  // Could move the edge planes slightly more inwards.
	  // But then again, the idea is that triangular patches bind into
	  // hierarchy of tringulas where such case would mean we are entering
	  // a new patch.
	  ISmess(_eh + RC.CollideInfo(true, R) + GForm(" Increasing ray-offset did not help - parking '%s'", GetName()));
	  SetDriveMode(DM_Parked);
	}
      }
      else
      {
	ISmess(_eh + RC.CollideInfo(true, R) + GForm(" Fallen off - parking, ray-offset was %f for '%s'.", mRayOffset, GetName()));
	SetDriveMode(DM_Parked);
      }
    }

    if (reoffset_count != 0)
    {
      mRayOffset = 2.0f * mTringula->GetMesh()->GetTTvor()->mMaxEdgeLen;
    }
  }
  else
  {
    ISwarn(_eh + RC.CollideInfo(false, R));
  }
}

//==============================================================================

void Crawler::ShootLaser()
{
  // Should move it up ... at least for half bbox ... and a bit forward.

  // We know laser is positioned in (0, 0, max_z) - by Crawler construction.
  // This should really be given from outside, somehow.

  HTransF& trans = ref_last_trans();

  Opcode::Ray ray;

  ray.mOrig = mLaserBeg;
  trans.RotateVec3IP(ray.mOrig);
  ray.mOrig.Add(trans.ref_pos());

  const Float_t p = mLaserLtRt.Get(), t = mLaserUpDn.Get();
  const Float_t ct = cosf(t);
  ray.mDir.Set(ct*cosf(p), ct*sinf(p), sinf(t));
  trans.RotateVec3IP(ray.mDir);

  ray.mOrig.TMac(ray.mDir, mLaserLen);

  mTringula->LaserShot(this, ray, mLaserCharge.Get());
  mLaserCharge.Set(0);
}
 Crawler.cxx:1
 Crawler.cxx:2
 Crawler.cxx:3
 Crawler.cxx:4
 Crawler.cxx:5
 Crawler.cxx:6
 Crawler.cxx:7
 Crawler.cxx:8
 Crawler.cxx:9
 Crawler.cxx:10
 Crawler.cxx:11
 Crawler.cxx:12
 Crawler.cxx:13
 Crawler.cxx:14
 Crawler.cxx:15
 Crawler.cxx:16
 Crawler.cxx:17
 Crawler.cxx:18
 Crawler.cxx:19
 Crawler.cxx:20
 Crawler.cxx:21
 Crawler.cxx:22
 Crawler.cxx:23
 Crawler.cxx:24
 Crawler.cxx:25
 Crawler.cxx:26
 Crawler.cxx:27
 Crawler.cxx:28
 Crawler.cxx:29
 Crawler.cxx:30
 Crawler.cxx:31
 Crawler.cxx:32
 Crawler.cxx:33
 Crawler.cxx:34
 Crawler.cxx:35
 Crawler.cxx:36
 Crawler.cxx:37
 Crawler.cxx:38
 Crawler.cxx:39
 Crawler.cxx:40
 Crawler.cxx:41
 Crawler.cxx:42
 Crawler.cxx:43
 Crawler.cxx:44
 Crawler.cxx:45
 Crawler.cxx:46
 Crawler.cxx:47
 Crawler.cxx:48
 Crawler.cxx:49
 Crawler.cxx:50
 Crawler.cxx:51
 Crawler.cxx:52
 Crawler.cxx:53
 Crawler.cxx:54
 Crawler.cxx:55
 Crawler.cxx:56
 Crawler.cxx:57
 Crawler.cxx:58
 Crawler.cxx:59
 Crawler.cxx:60
 Crawler.cxx:61
 Crawler.cxx:62
 Crawler.cxx:63
 Crawler.cxx:64
 Crawler.cxx:65
 Crawler.cxx:66
 Crawler.cxx:67
 Crawler.cxx:68
 Crawler.cxx:69
 Crawler.cxx:70
 Crawler.cxx:71
 Crawler.cxx:72
 Crawler.cxx:73
 Crawler.cxx:74
 Crawler.cxx:75
 Crawler.cxx:76
 Crawler.cxx:77
 Crawler.cxx:78
 Crawler.cxx:79
 Crawler.cxx:80
 Crawler.cxx:81
 Crawler.cxx:82
 Crawler.cxx:83
 Crawler.cxx:84
 Crawler.cxx:85
 Crawler.cxx:86
 Crawler.cxx:87
 Crawler.cxx:88
 Crawler.cxx:89
 Crawler.cxx:90
 Crawler.cxx:91
 Crawler.cxx:92
 Crawler.cxx:93
 Crawler.cxx:94
 Crawler.cxx:95
 Crawler.cxx:96
 Crawler.cxx:97
 Crawler.cxx:98
 Crawler.cxx:99
 Crawler.cxx:100
 Crawler.cxx:101
 Crawler.cxx:102
 Crawler.cxx:103
 Crawler.cxx:104
 Crawler.cxx:105
 Crawler.cxx:106
 Crawler.cxx:107
 Crawler.cxx:108
 Crawler.cxx:109
 Crawler.cxx:110
 Crawler.cxx:111
 Crawler.cxx:112
 Crawler.cxx:113
 Crawler.cxx:114
 Crawler.cxx:115
 Crawler.cxx:116
 Crawler.cxx:117
 Crawler.cxx:118
 Crawler.cxx:119
 Crawler.cxx:120
 Crawler.cxx:121
 Crawler.cxx:122
 Crawler.cxx:123
 Crawler.cxx:124
 Crawler.cxx:125
 Crawler.cxx:126
 Crawler.cxx:127
 Crawler.cxx:128
 Crawler.cxx:129
 Crawler.cxx:130
 Crawler.cxx:131
 Crawler.cxx:132
 Crawler.cxx:133
 Crawler.cxx:134
 Crawler.cxx:135
 Crawler.cxx:136
 Crawler.cxx:137
 Crawler.cxx:138
 Crawler.cxx:139
 Crawler.cxx:140
 Crawler.cxx:141
 Crawler.cxx:142
 Crawler.cxx:143
 Crawler.cxx:144
 Crawler.cxx:145
 Crawler.cxx:146
 Crawler.cxx:147
 Crawler.cxx:148
 Crawler.cxx:149
 Crawler.cxx:150
 Crawler.cxx:151
 Crawler.cxx:152
 Crawler.cxx:153
 Crawler.cxx:154
 Crawler.cxx:155
 Crawler.cxx:156
 Crawler.cxx:157
 Crawler.cxx:158
 Crawler.cxx:159
 Crawler.cxx:160
 Crawler.cxx:161
 Crawler.cxx:162
 Crawler.cxx:163
 Crawler.cxx:164
 Crawler.cxx:165
 Crawler.cxx:166
 Crawler.cxx:167
 Crawler.cxx:168
 Crawler.cxx:169
 Crawler.cxx:170
 Crawler.cxx:171
 Crawler.cxx:172
 Crawler.cxx:173
 Crawler.cxx:174
 Crawler.cxx:175
 Crawler.cxx:176
 Crawler.cxx:177
 Crawler.cxx:178
 Crawler.cxx:179
 Crawler.cxx:180
 Crawler.cxx:181
 Crawler.cxx:182
 Crawler.cxx:183
 Crawler.cxx:184
 Crawler.cxx:185
 Crawler.cxx:186
 Crawler.cxx:187
 Crawler.cxx:188
 Crawler.cxx:189
 Crawler.cxx:190
 Crawler.cxx:191
 Crawler.cxx:192
 Crawler.cxx:193
 Crawler.cxx:194
 Crawler.cxx:195
 Crawler.cxx:196
 Crawler.cxx:197
 Crawler.cxx:198
 Crawler.cxx:199
 Crawler.cxx:200
 Crawler.cxx:201
 Crawler.cxx:202
 Crawler.cxx:203
 Crawler.cxx:204
 Crawler.cxx:205
 Crawler.cxx:206
 Crawler.cxx:207
 Crawler.cxx:208
 Crawler.cxx:209
 Crawler.cxx:210
 Crawler.cxx:211
 Crawler.cxx:212
 Crawler.cxx:213
 Crawler.cxx:214
 Crawler.cxx:215
 Crawler.cxx:216
 Crawler.cxx:217
 Crawler.cxx:218
 Crawler.cxx:219
 Crawler.cxx:220
 Crawler.cxx:221
 Crawler.cxx:222
 Crawler.cxx:223
 Crawler.cxx:224
 Crawler.cxx:225
 Crawler.cxx:226
 Crawler.cxx:227
 Crawler.cxx:228
 Crawler.cxx:229
 Crawler.cxx:230
 Crawler.cxx:231
 Crawler.cxx:232
 Crawler.cxx:233
 Crawler.cxx:234
 Crawler.cxx:235
 Crawler.cxx:236
 Crawler.cxx:237
 Crawler.cxx:238
 Crawler.cxx:239
 Crawler.cxx:240
 Crawler.cxx:241
 Crawler.cxx:242
 Crawler.cxx:243
 Crawler.cxx:244
 Crawler.cxx:245
 Crawler.cxx:246
 Crawler.cxx:247
 Crawler.cxx:248
 Crawler.cxx:249
 Crawler.cxx:250
 Crawler.cxx:251
 Crawler.cxx:252
 Crawler.cxx:253
 Crawler.cxx:254
 Crawler.cxx:255
 Crawler.cxx:256
 Crawler.cxx:257
 Crawler.cxx:258
 Crawler.cxx:259
 Crawler.cxx:260
 Crawler.cxx:261
 Crawler.cxx:262
 Crawler.cxx:263
 Crawler.cxx:264
 Crawler.cxx:265
 Crawler.cxx:266
 Crawler.cxx:267
 Crawler.cxx:268
 Crawler.cxx:269
 Crawler.cxx:270
 Crawler.cxx:271
 Crawler.cxx:272
 Crawler.cxx:273
 Crawler.cxx:274
 Crawler.cxx:275
 Crawler.cxx:276
 Crawler.cxx:277
 Crawler.cxx:278
 Crawler.cxx:279
 Crawler.cxx:280
 Crawler.cxx:281
 Crawler.cxx:282
 Crawler.cxx:283
 Crawler.cxx:284
 Crawler.cxx:285
 Crawler.cxx:286
 Crawler.cxx:287
 Crawler.cxx:288