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/connectableentity.h"
35 
36 // appleseed.foundation headers.
37 #include "foundation/math/transform.h"
38 #include "foundation/math/vector.h"
39 #include "foundation/platform/compiler.h"
40 #include "foundation/utility/uid.h"
41 
42 // appleseed.main headers.
43 #include "main/dllsymbol.h"
44 
45 // Forward declarations.
46 namespace foundation    { class IAbortSwitch; }
47 namespace renderer      { class BaseGroup; }
48 namespace renderer      { class LightTargetArray; }
49 namespace renderer      { class OnFrameBeginRecorder; }
50 namespace renderer      { class ParamArray; }
51 namespace renderer      { class Project; }
52 namespace renderer      { class ShadingContext; }
53 
54 namespace renderer
55 {
56 
57 //
58 // Shape-less light.
59 //
60 
61 class APPLESEED_DLLSYMBOL Light
62   : public ConnectableEntity
63 {
64   public:
65     // Return the unique ID of this class of entities.
66     static foundation::UniqueID get_class_uid();
67 
68     // Constructor.
69     Light(
70         const char*                     name,
71         const ParamArray&               params);
72 
73     // Destructor.
74     ~Light() override;
75 
76     // Return a string identifying the model of this entity.
77     virtual const char* get_model() const = 0;
78 
79     enum Flags
80     {
81         CastIndirectLight = 1UL << 0,       // does this light generate indirect lighting?
82         LightTreeCompatible = 1UL << 1      // can this light be used by the LightTree?
83     };
84 
85     // Retrieve the flags.
86     int get_flags() const;
87 
88     // Retrieve the importance multiplier.
89     float get_uncached_importance_multiplier() const;
90 
91     // Set the light transformation.
92     void set_transform(const foundation::Transformd& transform);
93 
94     // Get the light transformation.
95     const foundation::Transformd& get_transform() const;
96 
97     bool on_frame_begin(
98         const Project&                  project,
99         const BaseGroup*                parent,
100         OnFrameBeginRecorder&           recorder,
101         foundation::IAbortSwitch*       abort_switch = nullptr) override;
102 
103     // Sample the light and compute the emission position, the emission direction,
104     // its probability density and the value of the light for this direction.
105     virtual void sample(
106         const ShadingContext&           shading_context,
107         const foundation::Transformd&   light_transform,            // light space to world space transform
108         const foundation::Vector3d&     target_point,               // world space target point
109         const foundation::Vector2d&     s,                          // sample in [0,1)^2
110         foundation::Vector3d&           position,                   // world space emission position
111         foundation::Vector3d&           outgoing,                   // world space emission direction, unit-length
112         Spectrum&                       value,                      // light value
113         float&                          probability) const = 0;     // PDF value
114     virtual void sample(
115         const ShadingContext&           shading_context,
116         const foundation::Transformd&   light_transform,            // light space to world space transform
117         const foundation::Vector2d&     s,                          // sample in [0,1)^2
118         foundation::Vector3d&           position,                   // world space emission position
119         foundation::Vector3d&           outgoing,                   // world space emission direction, unit-length
120         Spectrum&                       value,                      // light value
121         float&                          probability) const = 0;     // PDF value
122     virtual void sample(
123         const ShadingContext&           shading_context,
124         const foundation::Transformd&   light_transform,            // light space to world space transform
125         const foundation::Vector2d&     s,                          // sample in [0,1)^2
126         const LightTargetArray&         targets,
127         foundation::Vector3d&           position,                   // world space emission position
128         foundation::Vector3d&           outgoing,                   // world space emission direction, unit-length
129         Spectrum&                       value,                      // light value
130         float&                          probability) const;         // PDF value
131 
132     // Compute the distance attenuation of this light.
133     virtual float compute_distance_attenuation(
134         const foundation::Vector3d&     target,                     // world space target point
135         const foundation::Vector3d&     position) const = 0;        // world space emission position
136 
137   protected:
138     int m_flags;
139 
140   private:
141     struct Impl;
142     Impl* impl;
143 };
144 
145 
146 //
147 // Light class implementation.
148 //
149 
get_flags()150 inline int Light::get_flags() const
151 {
152     return m_flags;
153 }
154 
155 }   // namespace renderer
156