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) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29
30 #pragma once
31
32 // appleseed.renderer headers.
33 #include "renderer/kernel/lighting/lighttypes.h"
34
35 // appleseed.foundation headers.
36 #include "foundation/math/hash.h"
37 #include "foundation/utility/containers/hashtable.h"
38 #include "foundation/utility/uid.h"
39
40 // Standard headers.
41 #include <cstddef>
42 #include <vector>
43
44 // Forward declarations.
45 namespace renderer { class Intersector; }
46 namespace renderer { class Light; }
47 namespace renderer { class ShadingPoint; }
48
49 namespace renderer
50 {
51 //
52 // A key to uniquely identify a light-emitting shape in a hash table.
53 //
54
55 class EmittingShapeKey
56 {
57 public:
58 foundation::UniqueID m_assembly_instance_uid;
59 foundation::uint32 m_object_instance_index;
60 foundation::uint32 m_primitive_index;
61
62 EmittingShapeKey();
63 EmittingShapeKey(
64 const foundation::UniqueID assembly_instance_uid,
65 const size_t object_instance_index,
66 const size_t primitive_index);
67
68 bool operator==(const EmittingShapeKey& rhs) const;
69 };
70
71
72 //
73 // A hash table of light-emitting shapes.
74 //
75
76 struct EmittingShapeKeyHasher
77 {
78 size_t operator()(const EmittingShapeKey& key) const;
79 };
80
81 typedef foundation::HashTable<
82 EmittingShapeKey,
83 EmittingShapeKeyHasher,
84 const EmittingShape*
85 > EmittingShapeHashTable;
86
87
88 //
89 // Light sample: the result of sampling sets of non-physical lights and
90 // light-emitting shapes.
91 //
92
93 class LightSample
94 {
95 public:
96 LightSample();
97
98 // Data for a light-emitting shape sample.
99 const EmittingShape* m_shape;
100 foundation::Vector2f m_param_coords; // parametric coordinates of the sample
101 foundation::Vector3d m_point; // world space position of the sample
102 foundation::Vector3d m_shading_normal; // world space shading normal at the sample, unit-length
103 foundation::Vector3d m_geometric_normal; // world space geometric normal at the sample, unit-length
104
105 // Data for a non-physical light sample.
106 const Light* m_light;
107 foundation::Transformd m_light_transform; // light space to world space transform
108
109 // Data common to all sample types.
110 float m_probability; // probability density of this sample
111
112 // Construct a shading point out of this light sample and a given direction.
113 void make_shading_point(
114 ShadingPoint& shading_point,
115 const foundation::Vector3d& direction,
116 const Intersector& intersector) const;
117 };
118
119
120 //
121 // EmittingShapeKey class implementation.
122 //
123
EmittingShapeKey()124 inline EmittingShapeKey::EmittingShapeKey()
125 {
126 }
127
EmittingShapeKey(const foundation::UniqueID assembly_instance_uid,const size_t object_instance_index,const size_t primitive_index)128 inline EmittingShapeKey::EmittingShapeKey(
129 const foundation::UniqueID assembly_instance_uid,
130 const size_t object_instance_index,
131 const size_t primitive_index)
132 : m_assembly_instance_uid(static_cast<foundation::uint32>(assembly_instance_uid))
133 , m_object_instance_index(static_cast<foundation::uint32>(object_instance_index))
134 , m_primitive_index(static_cast<foundation::uint32>(primitive_index))
135 {
136 }
137
138 inline bool EmittingShapeKey::operator==(const EmittingShapeKey& rhs) const
139 {
140 return
141 m_primitive_index == rhs.m_primitive_index &&
142 m_object_instance_index == rhs.m_object_instance_index &&
143 m_assembly_instance_uid == rhs.m_assembly_instance_uid;
144 }
145
146
147 //
148 // EmittingShapeKeyHasher class implementation.
149 //
150
operator()151 inline size_t EmittingShapeKeyHasher::operator()(const EmittingShapeKey& key) const
152 {
153 return
154 foundation::mix_uint32(
155 static_cast<foundation::uint32>(key.m_assembly_instance_uid),
156 key.m_object_instance_index,
157 key.m_primitive_index);
158 }
159
160
161 //
162 // LightSample class implementation.
163 //
164
LightSample()165 inline LightSample::LightSample()
166 : m_shape(nullptr)
167 , m_light(nullptr)
168 {
169 }
170
make_shading_point(ShadingPoint & shading_point,const foundation::Vector3d & direction,const Intersector & intersector)171 inline void LightSample::make_shading_point(
172 ShadingPoint& shading_point,
173 const foundation::Vector3d& direction,
174 const Intersector& intersector) const
175 {
176 assert(m_shape && !m_light);
177
178 m_shape->make_shading_point(
179 shading_point,
180 m_point,
181 direction,
182 m_param_coords,
183 intersector);
184 }
185
186 } // namespace renderer
187