-
Notifications
You must be signed in to change notification settings - Fork 3
/
photon-shooter.h
149 lines (119 loc) · 3.83 KB
/
photon-shooter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// photon-shooter.h -- Photon-shooting infrastructure
//
// Copyright (C) 2010, 2011 Miles Bader <miles@gnu.org>
//
// This source code is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3, or (at
// your option) any later version. See the file COPYING for more details.
//
// Written by Miles Bader <miles@gnu.org>
//
#ifndef SNOGRAY_PHOTON_SHOOTER_H
#define SNOGRAY_PHOTON_SHOOTER_H
#include <vector>
#include "photon.h"
namespace snogray {
// A class used to shoot photons, for building photon maps. This is an
// abstract class, and must be subclassed.
//
class PhotonShooter
{
public:
PhotonShooter (const std::string &_name) : name (_name) { }
// A set of photons deposited during shooting. Subclasses usually
// have one or more PhotonSets which they are filling in.
//
class PhotonSet;
// Shoot photons from the lights, depositing them in photon-sets
// at appropriate points by calling PhotonSet::deposit.
//
void shoot (const GlobalRenderState &global_render_state);
// Deposit (or ignore) the photon PHOTON in some photon-set.
// ISEC is the intersection where the photon is being stored, and
// BSDF_HISTORY is the bitwise-or of all BSDF past interactions
// since this photon was emitted by the light (it will be zero for
// the first intersection).
//
// This method must be defined by subclasses.
//
virtual void deposit (const Photon &photon,
const Intersect &isec, unsigned bsdf_history)
= 0;
// Return true if all photon-sets are complete.
//
bool complete () const;
unsigned target_count () const;
unsigned cur_count () const;
// Pointers to photon-sets being filled in by this shooter. The
// actual photon-sets are located elsewhere (probably as a field
// in a subclass).
//
std::vector<PhotonSet *> photon_sets;
// Name of this photon-shooter, used for progress/status messages.
// Subclasses probably want to set this to something appropriate.
//
std::string name;
};
// A set of photons deposited during shooting. Subclasses usually
// have one or more PhotonSets which they are filling in.
//
class PhotonShooter::PhotonSet
{
public:
PhotonSet (unsigned _target_count, const std::string &_name,
PhotonShooter &shooter)
: num_paths (0), target_count (_target_count), name (_name)
{
shooter.photon_sets.push_back (this);
}
// Return true if this set has reached its target photon count.
//
bool complete () const { return photons.size () == target_count; }
// Deposited photons;
//
std::vector<Photon> photons;
// Number of paths tried so far in generating this set. This will
// be incremented for each new path until this set is declare done
// by setting the field PhotonSet::done to true.
//
unsigned num_paths;
// Number of photons we'd like to generate for this set.
//
unsigned target_count;
// Name of this set; this is used for generating messages after
// shooting.
//
std::string name;
};
// Return true if all photon-sets are complete.
//
inline bool
PhotonShooter::complete () const
{
for (std::vector<PhotonSet *>::const_iterator psi = photon_sets.begin();
psi != photon_sets.end(); ++psi)
if (! (*psi)->complete ())
return false;
return true;
}
inline unsigned
PhotonShooter::target_count () const
{
unsigned count = 0;
for (std::vector<PhotonSet *>::const_iterator psi = photon_sets.begin();
psi != photon_sets.end(); ++psi)
count += (*psi)->target_count;
return count;
}
inline unsigned
PhotonShooter::cur_count () const
{
unsigned count = 0;
for (std::vector<PhotonSet *>::const_iterator psi = photon_sets.begin();
psi != photon_sets.end(); ++psi)
count += (*psi)->photons.size ();
return count;
}
}
#endif // SNOGRAY_PHOTON_SHOOTER_H