1
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2015-2018 Francois Beaune, The appleseedhq Organization
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28
29 #pragma once
30
31 // appleseed.renderer headers.
32 #include "renderer/modeling/scene/visibilityflags.h"
33
34 // Standard headers.
35 #include <cassert>
36
37 namespace renderer
38 {
39
40 //
41 // All possible scattering modes.
42 //
43
44 class ScatteringMode
45 {
46 public:
47 enum ModeBitShift
48 {
49 DiffuseBitShift = 0,
50 GlossyBitShift = 1,
51 SpecularBitShift = 2,
52 VolumeBitShift = 3
53 };
54
55 enum Mode
56 {
57 None = 0,
58 Diffuse = 1UL << DiffuseBitShift,
59 Glossy = 1UL << GlossyBitShift,
60 Specular = 1UL << SpecularBitShift,
61 Volume = 1UL << VolumeBitShift,
62 All = Diffuse | Glossy | Specular | Volume
63 };
64
65 // Test for the presence of specific scattering modes.
66 static bool has_diffuse(const int modes);
67 static bool has_glossy(const int modes);
68 static bool has_specular(const int modes);
69 static bool has_volume(const int modes);
70 static bool has_diffuse_or_glossy_or_volume(const int modes);
71 static bool has_diffuse_and_glossy(const int modes);
72 static bool has_diffuse_or_volume(const int modes);
73 static bool has_glossy_or_specular(const int modes);
74
75 // Determine the appropriate visibility type for a given scattering mode.
76 static VisibilityFlags::Type get_vis_flags(const Mode mode);
77 };
78
79
80 //
81 // ScatteringMode class implementation.
82 //
83
has_diffuse(const int modes)84 inline bool ScatteringMode::has_diffuse(const int modes)
85 {
86 return (modes & Diffuse) != 0;
87 }
88
has_glossy(const int modes)89 inline bool ScatteringMode::has_glossy(const int modes)
90 {
91 return (modes & Glossy) != 0;
92 }
93
has_specular(const int modes)94 inline bool ScatteringMode::has_specular(const int modes)
95 {
96 return (modes & Specular) != 0;
97 }
98
has_volume(const int modes)99 inline bool ScatteringMode::has_volume(const int modes)
100 {
101 return (modes & Volume) != 0;
102 }
103
has_diffuse_or_glossy_or_volume(const int modes)104 inline bool ScatteringMode::has_diffuse_or_glossy_or_volume(const int modes)
105 {
106 return (modes & (Diffuse | Glossy | Volume)) != 0;
107 }
108
has_diffuse_and_glossy(const int modes)109 inline bool ScatteringMode::has_diffuse_and_glossy(const int modes)
110 {
111 return (modes & (Diffuse | Glossy)) == (Diffuse | Glossy);
112 }
113
has_diffuse_or_volume(const int modes)114 inline bool ScatteringMode::has_diffuse_or_volume(const int modes)
115 {
116 return (modes & (Diffuse | Volume)) != 0;
117 }
118
has_glossy_or_specular(const int modes)119 inline bool ScatteringMode::has_glossy_or_specular(const int modes)
120 {
121 return (modes & (Glossy | Specular)) != 0;
122 }
123
get_vis_flags(const Mode mode)124 inline VisibilityFlags::Type ScatteringMode::get_vis_flags(const Mode mode)
125 {
126 switch (mode)
127 {
128 case Diffuse:
129 return VisibilityFlags::DiffuseRay;
130
131 case Glossy:
132 return VisibilityFlags::GlossyRay;
133
134 case Specular:
135 return VisibilityFlags::SpecularRay;
136
137 default:
138 assert(!"Invalid scattering mode.");
139 return VisibilityFlags::DiffuseRay;
140 }
141 }
142
143 } // namespace renderer
144