Blender V5.0
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 pxr::UsdTimeCode time)
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, time)) {
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, time)) {
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, time)) {
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, time) && treatAsPoint) {
92 blight->radius = 0.0f;
93 }
94 else if (pxr::UsdAttribute radius_attr = sphere_light.GetRadiusAttr()) {
95 float radius = 0.0f;
96 if (radius_attr.Get(&radius, time)) {
97 blight->radius = radius;
98 }
99 }
100 }
101
102 pxr::UsdLuxShapingAPI shaping_api = pxr::UsdLuxShapingAPI(prim_);
103 if (shaping_api && shaping_api.GetShapingConeAngleAttr().IsAuthored()) {
104 blight->type = LA_SPOT;
105
106 if (pxr::UsdAttribute cone_angle_attr = shaping_api.GetShapingConeAngleAttr()) {
107 float cone_angle = 0.0f;
108 if (cone_angle_attr.Get(&cone_angle, time)) {
109 blight->spotsize = DEG2RADF(cone_angle) * 2.0f;
110 }
111 }
112
113 if (pxr::UsdAttribute cone_softness_attr = shaping_api.GetShapingConeSoftnessAttr()) {
114 float cone_softness = 0.0f;
115 if (cone_softness_attr.Get(&cone_softness, time)) {
116 blight->spotblend = cone_softness;
117 }
118 }
119 }
120 }
121 else if (prim_.IsA<pxr::UsdLuxDistantLight>()) {
122 blight->type = LA_SUN;
123
124 pxr::UsdLuxDistantLight distant_light(prim_);
125 if (distant_light) {
126 if (pxr::UsdAttribute angle_attr = distant_light.GetAngleAttr()) {
127 float angle = 0.0f;
128 if (angle_attr.Get(&angle, time)) {
129 blight->sun_angle = DEG2RADF(angle * 2.0f);
130 }
131 }
132 }
133 }
134
135 /* Intensity */
136 if (pxr::UsdAttribute intensity_attr = light_api.GetIntensityAttr()) {
137 float intensity = 0.0f;
138 if (intensity_attr.Get(&intensity, time)) {
139 if (blight->type == LA_SUN) {
140 /* Unclear why, but approximately matches Karma. */
141 blight->energy = intensity * 4.0f;
142 }
143 else {
144 /* Convert from intensity to radiant flux. */
145 blight->energy = intensity * M_PI;
146 }
147 blight->energy *= this->import_params_.light_intensity_scale;
148 }
149 }
150
151 /* Exposure. */
152 if (pxr::UsdAttribute exposure_attr = light_api.GetExposureAttr()) {
153 float exposure = 0.0f;
154 if (exposure_attr.Get(&exposure, time)) {
155 blight->exposure = exposure;
156 }
157 }
158
159 /* Color. */
160 if (pxr::UsdAttribute color_attr = light_api.GetColorAttr()) {
161 pxr::GfVec3f color;
162 if (color_attr.Get(&color, time)) {
163 blight->r = color[0];
164 blight->g = color[1];
165 blight->b = color[2];
166 }
167 }
168
169 /* Temperature */
170 if (pxr::UsdAttribute enable_temperature_attr = light_api.GetEnableColorTemperatureAttr()) {
171 bool enable_temperature = false;
172 if (enable_temperature_attr.Get(&enable_temperature, time)) {
173 if (enable_temperature) {
174 blight->mode |= LA_USE_TEMPERATURE;
175 }
176 }
177 }
178
179 if (pxr::UsdAttribute color_temperature_attr = light_api.GetColorTemperatureAttr()) {
180 float color_temperature = 6500.0f;
181 if (color_temperature_attr.Get(&color_temperature, time)) {
182 blight->temperature = color_temperature;
183 }
184 }
185
186 /* Diffuse and Specular. */
187 if (pxr::UsdAttribute diff_attr = light_api.GetDiffuseAttr()) {
188 float diff_fac = 1.0f;
189 if (diff_attr.Get(&diff_fac, time)) {
190 blight->diff_fac = diff_fac;
191 }
192 }
193 if (pxr::UsdAttribute spec_attr = light_api.GetSpecularAttr()) {
194 float spec_fac = 1.0f;
195 if (spec_attr.Get(&spec_fac, time)) {
196 blight->spec_fac = spec_fac;
197 }
198 }
199
200 /* Normalize */
201 if (pxr::UsdAttribute normalize_attr = light_api.GetNormalizeAttr()) {
202 bool normalize = false;
203 if (normalize_attr.Get(&normalize, time)) {
204 if (!normalize) {
205 blight->mode |= LA_UNNORMALIZED;
206 }
207 }
208 }
209
211}
212
213} // 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
@ LA_LOCAL
@ LA_SPOT
@ LA_SUN
@ LA_USE_TEMPERATURE
@ LA_UNNORMALIZED
@ LA_AREA_RECT
@ LA_AREA_DISK
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, pxr::UsdTimeCode time) override
const USDImportParams & import_params_
void read_object_data(Main *bmain, pxr::UsdTimeCode time) 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