ROOT logo
// $Id: TriMeshLightField.cxx 2363 2010-04-06 20:49:16Z 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/.

//__________________________________________________________________________
// TriMeshLightField
//
//

#include "TriMeshLightField.h"
#include <Glasses/ZNode.h>
#include "TriMeshLightField.c7"
#include "TriMesh.h"

#include <Stones/TringTvor.h>

#include <Opcode/Opcode.h>

#include <TMath.h>

ClassImp(TriMeshLightField);

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

void TriMeshLightField::_init()
{
  mAmbiLit      = 0.15;
  mAmbiShadowed = 0.1;
  mAmbiBackFace = 0.05;

  mLampPos.Zero();
  bDirectional = false;
}

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

void TriMeshLightField::ModulateColors(Bool_t regen_tring_cols)
{
  static const Exc_t _eh("TriMeshLightField::ModulateColors ");

  if (mDim != 1) throw _eh + "unsupported dimension.";

  TriMeshColorArraySource *carr_src =
    TriMeshColorArraySource::CastLens(_eh, *mColorArraySource, false);

  UChar_t *VCA = carr_src->GetVertexColorArray();
  if (!VCA)
    throw _eh + "color-array-source has no vertex-color-array.";

  assert_mesh(_eh);

  TringTvor &TT = * mMesh->GetTTvor();
  Float_t   *F  = FVec();
  UChar_t   *C  = VCA;
  for (Int_t i=0; i<TT.mNVerts; ++i, ++F, C+=4)
  {
    const Float_t f = * F;
    C[0] = UChar_t(f*C[0]);
    C[1] = UChar_t(f*C[1]);
    C[2] = UChar_t(f*C[2]);
  }

  // Regenerate changed triangles if necessary.
  UChar_t *TCA = carr_src->GetTriangleColorArray();
  if (regen_tring_cols && TCA)
  {
    TT.GenerateTriangleColorsFromVertexColors(VCA, TCA);
  }

  carr_src->ColorArraysModified();
}

void TriMeshLightField::PartiallyModulateColors(set<Int_t> vertices,
						Bool_t regen_tring_cols)
{
  static const Exc_t _eh("TriMeshLightField::PartiallyModulateColors ");

  if (mDim != 1) throw _eh + "unsupported dimension.";

  TriMeshColorArraySource *carr_src =
    TriMeshColorArraySource::CastLens(_eh, *mColorArraySource, false);

  UChar_t *VCA = carr_src->GetVertexColorArray();
  if (!VCA)
    throw _eh + "color-array-source has no vertex-color-array.";

  assert_mesh(_eh);

  for (set<Int_t>::iterator i=vertices.begin(); i!=vertices.end(); ++i)
  {
    const Float_t f = * FVec(*i);
    UChar_t* C = VCA + *i*4;
    C[0] = UChar_t(f*C[0]);
    C[1] = UChar_t(f*C[1]);
    C[2] = UChar_t(f*C[2]);
  }

  // Regenerate changed triangles if necessary.
  UChar_t *TCA = carr_src->GetTriangleColorArray();
  if (regen_tring_cols && TCA != 0)
  {
    set<Int_t> ct; // changed triangles
    for (set<Int_t>::iterator v = vertices.begin(); v != vertices.end(); ++v)
    {
      const TriMesh::VertexData & vd = mMesh->RefVDataVec()[*v];
      for (Int_t e = 0; e < vd.n_edges(); ++e)
      {
        const TriMesh::EdgeData& ed = mMesh->RefEDataVec()[vd.edge(e)];
        ct.insert(ed.fT1);
        ct.insert(ed.fT2); // Not needed for closed surfaces.
      }
    }
    if (*ct.begin() == -1) // Potentially remove no-tring entry.
      ct.erase(ct.begin());

    mMesh->GetTTvor()->GenerateTriangleColorsFromVertexColors(ct, VCA, TCA);
  }

  carr_src->ColorArraysModified();
}

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

void TriMeshLightField::CalculateLightField()
{
  static const Exc_t _eh("TriMeshLightField::CalculateLightField ");

  if (mDim != 1) throw(_eh + "unsupported dimension.");

  assert_mesh(_eh);
  TringTvor& TT = * mMesh->GetTTvor();

  Opcode::RayCollider RC;
  RC.SetCulling   (false);
  RC.SetClosestHit(true);

  Opcode::CollisionFaces CF;
  RC.SetDestination(&CF);

  Opcode::Ray   R;
  Opcode::Point nrdir(0, 0, 0); // normalized ray-direction

  if (bDirectional)
  {
    TT.AssertBoundingBox();
    Float_t max_dist = TT.BoundingBoxDiagonal();

    R.mDir.Set(mLampPos);
    nrdir   = R.mDir.Normalize();
    R.mDir *= - max_dist;
  }
  else
  {
    R.mOrig.Set(mLampPos);
  }

  Float_t* F = FVec();
  Float_t* V = TT.Verts();
  Float_t* N = TT.Norms();
  for (Int_t i=0; i<TT.mNVerts; ++i, ++F, V+=3, N+=3)
  {
    using namespace Opcode;
    Point& v = * (Opcode::Point*) V;
    Point& n = * (Opcode::Point*) N;

    if (bDirectional)
    {
      R.mOrig.Msc(v, R.mDir, 0.9999f);
    }
    else
    {
      R.mDir.Sub(v, R.mOrig);
      Float_t dist = R.mDir.Magnitude();
      nrdir   =  R.mDir;
      nrdir  *= -1.0f/dist;
      R.mDir *=  1.001f;
    }

    Float_t cos_alpha = n.Dot(nrdir);

    if (cos_alpha > 0)
    { // front-facing
      if ( ! RC.Collide(R, *mMesh->GetOPCModel()) )
        throw _eh + "collider failed:" + RC.CollideInfo(false, R);
      if (CF.GetNbFaces() == 0 || CF.GetFaces()[0].mDistance > 0.999f)
        *F = TMath::Max(cos_alpha, mAmbiLit);
      else
        *F = mAmbiShadowed;
    }
    else
    { // back-facing
      *F = mAmbiBackFace;
    }
  }
}

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

void TriMeshLightField::SetupLampPos(ZNode* lamp, ZNode* mesh)
{
  // Setup mLampPos for positional light at node 'lamp' and mesh at
  // node 'mesh'.
  // Member 'bDirectional' is not changed!

  static const Exc_t _eh("TriMeshLightField::SetupLampPos ");

  if (lamp == 0 || mesh == 0)
    throw(_eh + "requires non-null arguments.");

  auto_ptr<ZTrans> t (ZNode::BtoA(mesh, lamp));
  if (t.get() == 0)
    throw(_eh + "no path between arguments.");

  t->GetPos(mLampPos);
  Stamp(FID());
}

void TriMeshLightField::SetupLampDir(ZNode* mesh, Float_t theta, Float_t phi)
{
  // Setup mLampPos for directional light and mesh at node 'mesh'.
  // Arguments 'theta' and 'phi' determine direction towards the light
  // source in parent frame of the 'mesh'.
  // Member 'bDirectional' is not changed!

  static const Exc_t _eh("TriMeshLightField::SetupLampPos ");

  if (mesh == 0)
    throw(_eh + "requires non-null mesh argument.");

  ZTrans t(mesh->RefTrans());
  t.Invert();

  Double_t ct = TMath::Cos(theta);
  mLampPos.Set(ct*TMath::Cos(phi), ct*TMath::Sin(phi), TMath::Sin(theta));
  t.MultiplyIP(mLampPos);
  Stamp(FID());
}
 TriMeshLightField.cxx:1
 TriMeshLightField.cxx:2
 TriMeshLightField.cxx:3
 TriMeshLightField.cxx:4
 TriMeshLightField.cxx:5
 TriMeshLightField.cxx:6
 TriMeshLightField.cxx:7
 TriMeshLightField.cxx:8
 TriMeshLightField.cxx:9
 TriMeshLightField.cxx:10
 TriMeshLightField.cxx:11
 TriMeshLightField.cxx:12
 TriMeshLightField.cxx:13
 TriMeshLightField.cxx:14
 TriMeshLightField.cxx:15
 TriMeshLightField.cxx:16
 TriMeshLightField.cxx:17
 TriMeshLightField.cxx:18
 TriMeshLightField.cxx:19
 TriMeshLightField.cxx:20
 TriMeshLightField.cxx:21
 TriMeshLightField.cxx:22
 TriMeshLightField.cxx:23
 TriMeshLightField.cxx:24
 TriMeshLightField.cxx:25
 TriMeshLightField.cxx:26
 TriMeshLightField.cxx:27
 TriMeshLightField.cxx:28
 TriMeshLightField.cxx:29
 TriMeshLightField.cxx:30
 TriMeshLightField.cxx:31
 TriMeshLightField.cxx:32
 TriMeshLightField.cxx:33
 TriMeshLightField.cxx:34
 TriMeshLightField.cxx:35
 TriMeshLightField.cxx:36
 TriMeshLightField.cxx:37
 TriMeshLightField.cxx:38
 TriMeshLightField.cxx:39
 TriMeshLightField.cxx:40
 TriMeshLightField.cxx:41
 TriMeshLightField.cxx:42
 TriMeshLightField.cxx:43
 TriMeshLightField.cxx:44
 TriMeshLightField.cxx:45
 TriMeshLightField.cxx:46
 TriMeshLightField.cxx:47
 TriMeshLightField.cxx:48
 TriMeshLightField.cxx:49
 TriMeshLightField.cxx:50
 TriMeshLightField.cxx:51
 TriMeshLightField.cxx:52
 TriMeshLightField.cxx:53
 TriMeshLightField.cxx:54
 TriMeshLightField.cxx:55
 TriMeshLightField.cxx:56
 TriMeshLightField.cxx:57
 TriMeshLightField.cxx:58
 TriMeshLightField.cxx:59
 TriMeshLightField.cxx:60
 TriMeshLightField.cxx:61
 TriMeshLightField.cxx:62
 TriMeshLightField.cxx:63
 TriMeshLightField.cxx:64
 TriMeshLightField.cxx:65
 TriMeshLightField.cxx:66
 TriMeshLightField.cxx:67
 TriMeshLightField.cxx:68
 TriMeshLightField.cxx:69
 TriMeshLightField.cxx:70
 TriMeshLightField.cxx:71
 TriMeshLightField.cxx:72
 TriMeshLightField.cxx:73
 TriMeshLightField.cxx:74
 TriMeshLightField.cxx:75
 TriMeshLightField.cxx:76
 TriMeshLightField.cxx:77
 TriMeshLightField.cxx:78
 TriMeshLightField.cxx:79
 TriMeshLightField.cxx:80
 TriMeshLightField.cxx:81
 TriMeshLightField.cxx:82
 TriMeshLightField.cxx:83
 TriMeshLightField.cxx:84
 TriMeshLightField.cxx:85
 TriMeshLightField.cxx:86
 TriMeshLightField.cxx:87
 TriMeshLightField.cxx:88
 TriMeshLightField.cxx:89
 TriMeshLightField.cxx:90
 TriMeshLightField.cxx:91
 TriMeshLightField.cxx:92
 TriMeshLightField.cxx:93
 TriMeshLightField.cxx:94
 TriMeshLightField.cxx:95
 TriMeshLightField.cxx:96
 TriMeshLightField.cxx:97
 TriMeshLightField.cxx:98
 TriMeshLightField.cxx:99
 TriMeshLightField.cxx:100
 TriMeshLightField.cxx:101
 TriMeshLightField.cxx:102
 TriMeshLightField.cxx:103
 TriMeshLightField.cxx:104
 TriMeshLightField.cxx:105
 TriMeshLightField.cxx:106
 TriMeshLightField.cxx:107
 TriMeshLightField.cxx:108
 TriMeshLightField.cxx:109
 TriMeshLightField.cxx:110
 TriMeshLightField.cxx:111
 TriMeshLightField.cxx:112
 TriMeshLightField.cxx:113
 TriMeshLightField.cxx:114
 TriMeshLightField.cxx:115
 TriMeshLightField.cxx:116
 TriMeshLightField.cxx:117
 TriMeshLightField.cxx:118
 TriMeshLightField.cxx:119
 TriMeshLightField.cxx:120
 TriMeshLightField.cxx:121
 TriMeshLightField.cxx:122
 TriMeshLightField.cxx:123
 TriMeshLightField.cxx:124
 TriMeshLightField.cxx:125
 TriMeshLightField.cxx:126
 TriMeshLightField.cxx:127
 TriMeshLightField.cxx:128
 TriMeshLightField.cxx:129
 TriMeshLightField.cxx:130
 TriMeshLightField.cxx:131
 TriMeshLightField.cxx:132
 TriMeshLightField.cxx:133
 TriMeshLightField.cxx:134
 TriMeshLightField.cxx:135
 TriMeshLightField.cxx:136
 TriMeshLightField.cxx:137
 TriMeshLightField.cxx:138
 TriMeshLightField.cxx:139
 TriMeshLightField.cxx:140
 TriMeshLightField.cxx:141
 TriMeshLightField.cxx:142
 TriMeshLightField.cxx:143
 TriMeshLightField.cxx:144
 TriMeshLightField.cxx:145
 TriMeshLightField.cxx:146
 TriMeshLightField.cxx:147
 TriMeshLightField.cxx:148
 TriMeshLightField.cxx:149
 TriMeshLightField.cxx:150
 TriMeshLightField.cxx:151
 TriMeshLightField.cxx:152
 TriMeshLightField.cxx:153
 TriMeshLightField.cxx:154
 TriMeshLightField.cxx:155
 TriMeshLightField.cxx:156
 TriMeshLightField.cxx:157
 TriMeshLightField.cxx:158
 TriMeshLightField.cxx:159
 TriMeshLightField.cxx:160
 TriMeshLightField.cxx:161
 TriMeshLightField.cxx:162
 TriMeshLightField.cxx:163
 TriMeshLightField.cxx:164
 TriMeshLightField.cxx:165
 TriMeshLightField.cxx:166
 TriMeshLightField.cxx:167
 TriMeshLightField.cxx:168
 TriMeshLightField.cxx:169
 TriMeshLightField.cxx:170
 TriMeshLightField.cxx:171
 TriMeshLightField.cxx:172
 TriMeshLightField.cxx:173
 TriMeshLightField.cxx:174
 TriMeshLightField.cxx:175
 TriMeshLightField.cxx:176
 TriMeshLightField.cxx:177
 TriMeshLightField.cxx:178
 TriMeshLightField.cxx:179
 TriMeshLightField.cxx:180
 TriMeshLightField.cxx:181
 TriMeshLightField.cxx:182
 TriMeshLightField.cxx:183
 TriMeshLightField.cxx:184
 TriMeshLightField.cxx:185
 TriMeshLightField.cxx:186
 TriMeshLightField.cxx:187
 TriMeshLightField.cxx:188
 TriMeshLightField.cxx:189
 TriMeshLightField.cxx:190
 TriMeshLightField.cxx:191
 TriMeshLightField.cxx:192
 TriMeshLightField.cxx:193
 TriMeshLightField.cxx:194
 TriMeshLightField.cxx:195
 TriMeshLightField.cxx:196
 TriMeshLightField.cxx:197
 TriMeshLightField.cxx:198
 TriMeshLightField.cxx:199
 TriMeshLightField.cxx:200
 TriMeshLightField.cxx:201
 TriMeshLightField.cxx:202
 TriMeshLightField.cxx:203
 TriMeshLightField.cxx:204
 TriMeshLightField.cxx:205
 TriMeshLightField.cxx:206
 TriMeshLightField.cxx:207
 TriMeshLightField.cxx:208
 TriMeshLightField.cxx:209
 TriMeshLightField.cxx:210
 TriMeshLightField.cxx:211
 TriMeshLightField.cxx:212
 TriMeshLightField.cxx:213
 TriMeshLightField.cxx:214
 TriMeshLightField.cxx:215
 TriMeshLightField.cxx:216
 TriMeshLightField.cxx:217
 TriMeshLightField.cxx:218
 TriMeshLightField.cxx:219
 TriMeshLightField.cxx:220
 TriMeshLightField.cxx:221
 TriMeshLightField.cxx:222
 TriMeshLightField.cxx:223
 TriMeshLightField.cxx:224
 TriMeshLightField.cxx:225
 TriMeshLightField.cxx:226
 TriMeshLightField.cxx:227
 TriMeshLightField.cxx:228
 TriMeshLightField.cxx:229
 TriMeshLightField.cxx:230
 TriMeshLightField.cxx:231
 TriMeshLightField.cxx:232
 TriMeshLightField.cxx:233
 TriMeshLightField.cxx:234
 TriMeshLightField.cxx:235
 TriMeshLightField.cxx:236
 TriMeshLightField.cxx:237
 TriMeshLightField.cxx:238
 TriMeshLightField.cxx:239