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/global/globaltypes.h"
34 #include "renderer/modeling/entity/entity.h"
35 #include "renderer/modeling/scene/containers.h"
36
37 // appleseed.foundation headers.
38 #include "foundation/math/transform.h"
39 #include "foundation/platform/compiler.h"
40 #include "foundation/platform/types.h"
41 #include "foundation/utility/api/apiarray.h"
42 #include "foundation/utility/autoreleaseptr.h"
43 #include "foundation/utility/uid.h"
44
45 // appleseed.main headers.
46 #include "main/dllsymbol.h"
47
48 // Standard headers.
49 #include <cassert>
50 #include <cstddef>
51
52 // Forward declarations.
53 namespace foundation { class DictionaryArray; }
54 namespace foundation { class IAbortSwitch; }
55 namespace foundation { class StringDictionary; }
56 namespace renderer { class Assembly; }
57 namespace renderer { class Material; }
58 namespace renderer { class Object; }
59 namespace renderer { class OnFrameBeginRecorder; }
60 namespace renderer { class ParamArray; }
61 namespace renderer { class Project; }
62
63 namespace renderer
64 {
65
66 //
67 // An array of materials.
68 //
69
70 APPLESEED_DECLARE_APIARRAY(MaterialArray, const Material*);
71
72 // Return true if at least one material in the array emits light.
73 bool has_emitting_materials(const MaterialArray& materials);
74
75 // Return true if at least one material in the array has an alpha map set.
76 bool uses_alpha_mapping(const MaterialArray& materials);
77
78
79 //
80 // An instance of an object.
81 //
82
83 class APPLESEED_DLLSYMBOL ObjectInstance
84 : public Entity
85 {
86 public:
87 // Return the unique ID of this class of entities.
88 static foundation::UniqueID get_class_uid();
89
90 // Delete this instance.
91 void release() override;
92
93 // Compute and return the unique signature of this instance.
94 foundation::uint64 compute_signature() const override;
95
96 // Return the name of the instantiated object.
97 const char* get_object_name() const;
98
99 // Return the transform of this instance.
100 const foundation::Transformd& get_transform() const;
101
102 // Return true if the transform of this instance swaps handedness.
103 bool transform_swaps_handedness() const;
104
105 // Return true if the normals of this instance must be flipped.
106 bool must_flip_normals() const;
107
108 // Return or set visibility flags of this instance.
109 foundation::uint32 get_vis_flags() const;
110 void set_vis_flags(const foundation::uint32 flags);
111
112 // Return the medium priority of this instance.
113 foundation::int8 get_medium_priority() const;
114
115 enum RayBiasMethod
116 {
117 RayBiasMethodNone, // no ray bias for this object instance
118 RayBiasMethodNormal, // shift the ray's origin along the surface's geometric normal
119 RayBiasMethodIncomingDirection, // shift the ray's origin along the incoming ray's direction
120 RayBiasMethodOutgoingDirection // shift the ray's origin along the outgoing ray's direction
121 };
122
123 // Return the ray bias settings. The bias distance is expressed in world space.
124 RayBiasMethod get_ray_bias_method() const;
125 double get_ray_bias_distance() const;
126
127 // Check if this object instance is in the same SSS set as another.
128 bool is_in_same_sss_set(const ObjectInstance& other) const;
129
130 // Find the object bound to this instance.
131 Object* find_object() const;
132
133 // Compute the parent space bounding box of the instance.
134 GAABB3 compute_parent_bbox() const;
135
136 // Sides of this object instance's surface.
137 enum Side
138 {
139 FrontSide = 1UL << 0,
140 BackSide = 1UL << 1,
141 BothSides = FrontSide | BackSide
142 };
143
144 // Clear all material assignments.
145 void clear_front_materials();
146 void clear_back_materials();
147
148 // Assign a material to a given slot.
149 void assign_material(
150 const char* slot,
151 const Side side,
152 const char* name);
153
154 // Unassign a material from a given slot.
155 void unassign_material(
156 const char* slot,
157 const Side side);
158
159 // Return the slot-to-material mappings of this instance.
160 foundation::StringDictionary& get_front_material_mappings() const;
161 foundation::StringDictionary& get_back_material_mappings() const;
162
163 // Get the name of the material bound to a given primitive of this instance.
164 const char* get_material_name(const size_t pa_index, const Side side) const;
165
166 // Object binding.
167 void unbind_object();
168 void bind_object(const ObjectContainer& objects);
169 void check_object() const;
170
171 // Material binding.
172 void unbind_materials();
173 void bind_materials(const MaterialContainer& materials);
174 void check_materials() const;
175
176 // Return the object bound to this instance.
177 Object& get_object() const;
178
179 // Return the materials bound to this instance.
180 const MaterialArray& get_front_materials() const;
181 const MaterialArray& get_back_materials() const;
182
183 // Return true if at least one of the material referenced by this instance
184 // has a volume assigned to it.
185 bool has_participating_media() const;
186
187 // Return true if at least one of the material referenced by this instance has an alpha map set.
188 bool uses_alpha_mapping() const;
189
190 bool on_frame_begin(
191 const Project& project,
192 const BaseGroup* parent,
193 OnFrameBeginRecorder& recorder,
194 foundation::IAbortSwitch* abort_switch = nullptr) override;
195
196 private:
197 friend class ObjectInstanceFactory;
198
199 struct Impl;
200 Impl* impl;
201
202 foundation::uint32 m_vis_flags;
203 foundation::int8 m_medium_priority;
204 RayBiasMethod m_ray_bias_method;
205 double m_ray_bias_distance;
206 bool m_transform_swaps_handedness;
207 bool m_flip_normals;
208
209 Object* m_object;
210 MaterialArray m_front_materials;
211 MaterialArray m_back_materials;
212
213 // Constructor.
214 ObjectInstance(
215 const char* name,
216 const ParamArray& params,
217 const char* object_name,
218 const foundation::Transformd& transform,
219 const foundation::StringDictionary& front_material_mappings,
220 const foundation::StringDictionary& back_material_mappings);
221
222 // Destructor.
223 ~ObjectInstance() override;
224 };
225
226
227 //
228 // Object instance factory.
229 //
230
231 class APPLESEED_DLLSYMBOL ObjectInstanceFactory
232 {
233 public:
234 // Return a set of input metadata for object instance entities.
235 static foundation::DictionaryArray get_input_metadata();
236
237 // Create a new object instance.
238 static foundation::auto_release_ptr<ObjectInstance> create(
239 const char* name,
240 const ParamArray& params,
241 const char* object_name,
242 const foundation::Transformd& transform,
243 const foundation::StringDictionary& front_material_mappings,
244 const foundation::StringDictionary& back_material_mappings = foundation::StringDictionary());
245 };
246
247
248 //
249 // ObjectInstance class implementation.
250 //
251
transform_swaps_handedness()252 inline bool ObjectInstance::transform_swaps_handedness() const
253 {
254 return m_transform_swaps_handedness;
255 }
256
must_flip_normals()257 inline bool ObjectInstance::must_flip_normals() const
258 {
259 return m_flip_normals;
260 }
261
get_vis_flags()262 inline foundation::uint32 ObjectInstance::get_vis_flags() const
263 {
264 return m_vis_flags;
265 }
266
set_vis_flags(const foundation::uint32 flags)267 inline void ObjectInstance::set_vis_flags(const foundation::uint32 flags)
268 {
269 m_vis_flags = flags;
270 }
271
get_medium_priority()272 inline foundation::int8 ObjectInstance::get_medium_priority() const
273 {
274 return m_medium_priority;
275 }
276
get_ray_bias_method()277 inline ObjectInstance::RayBiasMethod ObjectInstance::get_ray_bias_method() const
278 {
279 return m_ray_bias_method;
280 }
281
get_ray_bias_distance()282 inline double ObjectInstance::get_ray_bias_distance() const
283 {
284 return m_ray_bias_distance;
285 }
286
get_object()287 inline Object& ObjectInstance::get_object() const
288 {
289 assert(m_object);
290 return *m_object;
291 }
292
get_front_materials()293 inline const MaterialArray& ObjectInstance::get_front_materials() const
294 {
295 return m_front_materials;
296 }
297
get_back_materials()298 inline const MaterialArray& ObjectInstance::get_back_materials() const
299 {
300 return m_back_materials;
301 }
302
303 } // namespace renderer
304