MEPP2 Project
lightsampler.inl
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 
12 inline
13 void
14 LightSampler::sample(MatrixX3d &samples,
15  int n,
16  double phi_min,
17  double phi_max,
18  Method method,
19  bool use_random) const
20 {
21  switch(method)
22  {
23  case NAIVE:
24  default:
25  sample_naive(samples, n, phi_min, phi_max, use_random);
26  break;
27  }
28 }
29 
30 inline
31 void
32 LightSampler::sample_to_global(MatrixX3d &samples,
33  int n,
34  const Vector3d &up,
35  double phi_min,
36  double phi_max,
37  bool use_random,
38  Method method) const
39 {
40  MatrixX3d local;
41  sample(local, n, phi_min, phi_max, method, use_random);
42  to_global(local, samples, up);
43 }
44 
45 inline
46 void
47 LightSampler::to_global(const MatrixX3d &local,
48  MatrixX3d &global,
49  const Vector3d &up) const
50 {
51  Vector3d oUp(Vector3d::UnitZ());
52 
53  double c = oUp.dot(up);
54  if(c == 1.) // nothing to do
55  global = local;
56  else if(c == -1.) // opposite direction
57  global = -local;
58  else
59  {
60  Vector3d v = oUp.cross(up);
61  Matrix3d vx;
62  vx << 0, -v(2), v(1), v(2), 0, -v(0), -v(1), v(0), 0;
63  vx = -vx;
64 
65  // compute rotation matrix
66  Matrix3d R = Matrix3d::Identity() + vx + vx * vx / (1 + c);
67 
68  global = local * R;
69  }
70 }
71 
72 inline
73 void
74 LightSampler::sample_naive(MatrixX3d &samples,
75  int n,
76  double phi_min,
77  double phi_max,
78  bool use_random) const
79 {
80  samples.resize(n, 3);
81  samples.setZero();
82 
83  std::random_device rd;
84  std::mt19937 gen = std::mt19937(rd());
85 
86  double pi_2 = 2.0 * M_PI;
87  double a = phi_min < phi_max ? phi_min : phi_max;
88  double b = phi_min < phi_max ? phi_max : phi_min;
89  std::uniform_real_distribution< double > dis1(0.0, pi_2);
90  std::uniform_real_distribution< double > dis2(a, b);
91 
92  double step1 = pi_2 / (double)n;
93  double step2 = 4.0 * (b - a) / (double)n;
94  for(int i = 0; i < n; ++i)
95  {
96  double theta;
97  double phi;
98  if(use_random)
99  {
100  theta = dis1(gen);
101  phi = dis2(gen);
102  }
103  else
104  {
105  theta = i * step1;
106  phi = a + i * step2;
107  while(phi > b)
108  phi -= (b - a);
109  }
110 
111  samples.row(i) << cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi);
112  }
113 }
LightSampler::sample_naive
void sample_naive(MatrixX3d &samples, int n, double phi_min=0., double phi_max=M_PI, bool use_random=true) const
Definition: lightsampler.inl:74
LightSampler::sample
void sample(MatrixX3d &samples, int n, double phi_min=0., double phi_max=M_PI, Method method=NAIVE, bool use_random=true) const
Definition: lightsampler.inl:14
LightSampler::Method
Method
Definition: lightsampler.hpp:22
LightSampler::NAIVE
@ NAIVE
Definition: lightsampler.hpp:22
LightSampler::to_global
void to_global(const MatrixX3d &local, MatrixX3d &global, const Vector3d &up=Vector3d::UnitZ()) const
Definition: lightsampler.inl:47
LightSampler::sample_to_global
void sample_to_global(MatrixX3d &samples, int n, const Vector3d &up=Vector3d::UnitZ(), double phi_min=0., double phi_max=M_PI, bool use_random=true, Method method=NAIVE) const
Definition: lightsampler.inl:32