Blender V4.5
usd_reader_light.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Tangent Animation. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "usd_reader_light.hh"
6
7#include "BLI_math_rotation.h"
8
9#include "BKE_light.h"
10#include "BKE_object.hh"
11
13
14#include "DNA_light_types.h"
15#include "DNA_object_types.h"
16
17#include <pxr/usd/usdLux/diskLight.h>
18#include <pxr/usd/usdLux/distantLight.h>
19#include <pxr/usd/usdLux/rectLight.h>
20#include <pxr/usd/usdLux/shapingAPI.h>
21#include <pxr/usd/usdLux/sphereLight.h>
22
23namespace blender::io::usd {
24
26{
27 Light *blight = BKE_light_add(bmain, name_.c_str());
28
30 object_->data = blight;
31}
32
33void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime)
34{
35 Light *blight = (Light *)object_->data;
36
37 if (blight == nullptr) {
38 return;
39 }
40
41 pxr::UsdLuxLightAPI light_api(prim_);
42 if (!light_api) {
43 return;
44 }
45
46 if (prim_.IsA<pxr::UsdLuxDiskLight>()) {
47 /* Disk area light. */
48 blight->type = LA_AREA;
49 blight->area_shape = LA_AREA_DISK;
50
51 pxr::UsdLuxDiskLight disk_light(prim_);
52 if (disk_light) {
53 if (pxr::UsdAttribute radius_attr = disk_light.GetRadiusAttr()) {
54 float radius = 0.0f;
55 if (radius_attr.Get(&radius, motionSampleTime)) {
56 blight->area_size = radius * 2.0f;
57 }
58 }
59 }
60 }
61 else if (prim_.IsA<pxr::UsdLuxRectLight>()) {
62 /* Rectangular area light. */
63 blight->type = LA_AREA;
64 blight->area_shape = LA_AREA_RECT;
65
66 pxr::UsdLuxRectLight rect_light(prim_);
67 if (rect_light) {
68 if (pxr::UsdAttribute width_attr = rect_light.GetWidthAttr()) {
69 float width = 0.0f;
70 if (width_attr.Get(&width, motionSampleTime)) {
71 blight->area_size = width;
72 }
73 }
74
75 if (pxr::UsdAttribute height_attr = rect_light.GetHeightAttr()) {
76 float height = 0.0f;
77 if (height_attr.Get(&height, motionSampleTime)) {
78 blight->area_sizey = height;
79 }
80 }
81 }
82 }
83 else if (prim_.IsA<pxr::UsdLuxSphereLight>()) {
84 /* Point and spot light. */
85 blight->type = LA_LOCAL;
86
87 pxr::UsdLuxSphereLight sphere_light(prim_);
88 if (sphere_light) {
89 pxr::UsdAttribute treatAsPoint_attr = sphere_light.GetTreatAsPointAttr();
90 bool treatAsPoint;
91 if (treatAsPoint_attr && treatAsPoint_attr.Get(&treatAsPoint, motionSampleTime) &&
92 treatAsPoint)
93 {
94 blight->radius = 0.0f;
95 }
96 else if (pxr::UsdAttribute radius_attr = sphere_light.GetRadiusAttr()) {
97 float radius = 0.0f;
98 if (radius_attr.Get(&radius, motionSampleTime)) {
99 blight->radius = radius;
100 }
101 }
102 }
103
104 pxr::UsdLuxShapingAPI shaping_api = pxr::UsdLuxShapingAPI(prim_);
105 if (shaping_api && shaping_api.GetShapingConeAngleAttr().IsAuthored()) {
106 blight->type = LA_SPOT;
107
108 if (pxr::UsdAttribute cone_angle_attr = shaping_api.GetShapingConeAngleAttr()) {
109 float cone_angle = 0.0f;
110 if (cone_angle_attr.Get(&cone_angle, motionSampleTime)) {
111 blight->spotsize = DEG2RADF(cone_angle) * 2.0f;
112 }
113 }
114
115 if (pxr::UsdAttribute cone_softness_attr = shaping_api.GetShapingConeSoftnessAttr()) {
116 float cone_softness = 0.0f;
117 if (cone_softness_attr.Get(&cone_softness, motionSampleTime)) {
118 blight->spotblend = cone_softness;
119 }
120 }
121 }
122 }
123 else if (prim_.IsA<pxr::UsdLuxDistantLight>()) {
124 blight->type = LA_SUN;
125
126 pxr::UsdLuxDistantLight distant_light(prim_);
127 if (distant_light) {
128 if (pxr::UsdAttribute angle_attr = distant_light.GetAngleAttr()) {
129 float angle = 0.0f;
130 if (angle_attr.Get(&angle, motionSampleTime)) {
131 blight->sun_angle = DEG2RADF(angle * 2.0f);
132 }
133 }
134 }
135 }
136
137 /* Intensity */
138 if (pxr::UsdAttribute intensity_attr = light_api.GetIntensityAttr()) {
139 float intensity = 0.0f;
140 if (intensity_attr.Get(&intensity, motionSampleTime)) {
141 if (blight->type == LA_SUN) {
142 /* Unclear why, but approximately matches Karma. */
143 blight->energy = intensity * 4.0f;
144 }
145 else {
146 /* Convert from intensity to radiant flux. */
147 blight->energy = intensity * M_PI;
148 }
149 blight->energy *= this->import_params_.light_intensity_scale;
150 }
151 }
152
153 /* Exposure. */
154 if (pxr::UsdAttribute exposure_attr = light_api.GetExposureAttr()) {
155 float exposure = 0.0f;
156 if (exposure_attr.Get(&exposure, motionSampleTime)) {
157 blight->exposure = exposure;
158 }
159 }
160
161 /* Color. */
162 if (pxr::UsdAttribute color_attr = light_api.GetColorAttr()) {
163 pxr::GfVec3f color;
164 if (color_attr.Get(&color, motionSampleTime)) {
165 blight->r = color[0];
166 blight->g = color[1];
167 blight->b = color[2];
168 }
169 }
170
171 /* Temperature */
172 if (pxr::UsdAttribute enable_temperature_attr = light_api.GetEnableColorTemperatureAttr()) {
173 bool enable_temperature = false;
174 if (enable_temperature_attr.Get(&enable_temperature, motionSampleTime)) {
175 if (enable_temperature) {
176 blight->mode |= LA_USE_TEMPERATURE;
177 }
178 }
179 }
180
181 if (pxr::UsdAttribute color_temperature_attr = light_api.GetColorTemperatureAttr()) {
182 float color_temperature = 6500.0f;
183 if (color_temperature_attr.Get(&color_temperature, motionSampleTime)) {
184 blight->temperature = color_temperature;
185 }
186 }
187
188 /* Diffuse and Specular. */
189 if (pxr::UsdAttribute diff_attr = light_api.GetDiffuseAttr()) {
190 float diff_fac = 1.0f;
191 if (diff_attr.Get(&diff_fac, motionSampleTime)) {
192 blight->diff_fac = diff_fac;
193 }
194 }
195 if (pxr::UsdAttribute spec_attr = light_api.GetSpecularAttr()) {
196 float spec_fac = 1.0f;
197 if (spec_attr.Get(&spec_fac, motionSampleTime)) {
198 blight->spec_fac = spec_fac;
199 }
200 }
201
202 /* Normalize */
203 if (pxr::UsdAttribute normalize_attr = light_api.GetNormalizeAttr()) {
204 bool normalize = false;
205 if (normalize_attr.Get(&normalize, motionSampleTime)) {
206 if (!normalize) {
207 blight->mode |= LA_UNNORMALIZED;
208 }
209 }
210 }
211
212 USDXformReader::read_object_data(bmain, motionSampleTime);
213}
214
215} // namespace blender::io::usd
General operations, lookup, etc. for blender lights.
Light * BKE_light_add(Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
#define DEG2RADF(_deg)
#define M_PI
@ LA_AREA_RECT
@ LA_AREA_DISK
@ LA_USE_TEMPERATURE
@ LA_UNNORMALIZED
@ LA_AREA
@ LA_LOCAL
@ LA_SPOT
@ LA_SUN
Object is a sort of wrapper for general info.
@ OB_LAMP
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void create_object(Main *bmain) override
void read_object_data(Main *bmain, double motionSampleTime) override
const USDImportParams & import_params_
void read_object_data(Main *bmain, double motionSampleTime) override
VecBase< float, D > normalize(VecOp< float, D >) RET
float sun_angle
float energy
float temperature
float spec_fac
float area_sizey
short area_shape
float spotblend
float spotsize
float exposure
float radius
float area_size
short type
float diff_fac