Blender  V3.3
usd_writer_light.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2019 Blender Foundation. All rights reserved. */
3 #include "usd_writer_light.h"
5 
6 #include <pxr/usd/usdLux/diskLight.h>
7 #include <pxr/usd/usdLux/distantLight.h>
8 #include <pxr/usd/usdLux/rectLight.h>
9 #include <pxr/usd/usdLux/sphereLight.h>
10 
11 #include "BLI_assert.h"
12 #include "BLI_utildefines.h"
13 
14 #include "DNA_light_types.h"
15 #include "DNA_object_types.h"
16 
17 namespace blender::io::usd {
18 
20 {
21 }
22 
24 {
25  Light *light = static_cast<Light *>(context->object->data);
26  return ELEM(light->type, LA_AREA, LA_LOCAL, LA_SUN);
27 }
28 
30 {
31  pxr::UsdStageRefPtr stage = usd_export_context_.stage;
32  const pxr::SdfPath &usd_path = usd_export_context_.usd_path;
33  pxr::UsdTimeCode timecode = get_export_time_code();
34 
35  Light *light = static_cast<Light *>(context.object->data);
36 #if PXR_VERSION >= 2111
37  pxr::UsdLuxLightAPI usd_light_api;
38 #else
39  pxr::UsdLuxLight usd_light_api;
40 
41 #endif
42 
43  switch (light->type) {
44  case LA_AREA:
45  switch (light->area_shape) {
46  case LA_AREA_DISK:
47  case LA_AREA_ELLIPSE: { /* An ellipse light will deteriorate into a disk light. */
48  pxr::UsdLuxDiskLight disk_light = pxr::UsdLuxDiskLight::Define(stage, usd_path);
49  disk_light.CreateRadiusAttr().Set(light->area_size, timecode);
50 #if PXR_VERSION >= 2111
51  usd_light_api = disk_light.LightAPI();
52 #else
53  usd_light_api = disk_light;
54 #endif
55  break;
56  }
57  case LA_AREA_RECT: {
58  pxr::UsdLuxRectLight rect_light = pxr::UsdLuxRectLight::Define(stage, usd_path);
59  rect_light.CreateWidthAttr().Set(light->area_size, timecode);
60  rect_light.CreateHeightAttr().Set(light->area_sizey, timecode);
61 #if PXR_VERSION >= 2111
62  usd_light_api = rect_light.LightAPI();
63 #else
64  usd_light_api = rect_light;
65 #endif
66  break;
67  }
68  case LA_AREA_SQUARE: {
69  pxr::UsdLuxRectLight rect_light = pxr::UsdLuxRectLight::Define(stage, usd_path);
70  rect_light.CreateWidthAttr().Set(light->area_size, timecode);
71  rect_light.CreateHeightAttr().Set(light->area_size, timecode);
72 #if PXR_VERSION >= 2111
73  usd_light_api = rect_light.LightAPI();
74 #else
75  usd_light_api = rect_light;
76 #endif
77  break;
78  }
79  }
80  break;
81  case LA_LOCAL: {
82  pxr::UsdLuxSphereLight sphere_light = pxr::UsdLuxSphereLight::Define(stage, usd_path);
83  sphere_light.CreateRadiusAttr().Set(light->area_size, timecode);
84 #if PXR_VERSION >= 2111
85  usd_light_api = sphere_light.LightAPI();
86 #else
87  usd_light_api = sphere_light;
88 #endif
89  break;
90  }
91  case LA_SUN: {
92  pxr::UsdLuxDistantLight distant_light = pxr::UsdLuxDistantLight::Define(stage, usd_path);
93  /* TODO(makowalski): set angle attribute here. */
94 #if PXR_VERSION >= 2111
95  usd_light_api = distant_light.LightAPI();
96 #else
97  usd_light_api = distant_light;
98 #endif
99  break;
100  }
101  default:
102  BLI_assert_msg(0, "is_supported() returned true for unsupported light type");
103  }
104 
105  /* Scale factor to get to somewhat-similar illumination. Since the USDViewer had similar
106  * over-exposure as Blender Internal with the same values, this code applies the reverse of the
107  * versioning code in light_emission_unify(). */
108  float usd_intensity;
109  if (light->type == LA_SUN) {
110  /* Untested, as the Hydra GL viewport of USDViewer doesn't support distant lights. */
111  usd_intensity = light->energy;
112  }
113  else {
114  usd_intensity = light->energy / 100.0f;
115  }
116  usd_light_api.CreateIntensityAttr().Set(usd_intensity, timecode);
117 
118  usd_light_api.CreateColorAttr().Set(pxr::GfVec3f(light->r, light->g, light->b), timecode);
119  usd_light_api.CreateSpecularAttr().Set(light->spec_fac, timecode);
120 }
121 
122 } // namespace blender::io::usd
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#define ELEM(...)
#define LA_AREA
#define LA_AREA_SQUARE
#define LA_AREA_ELLIPSE
#define LA_SUN
#define LA_LOCAL
#define LA_AREA_DISK
#define LA_AREA_RECT
Object is a sort of wrapper for general info.
const pxr::SdfPath & usd_path() const
pxr::UsdTimeCode get_export_time_code() const
const USDExporterContext usd_export_context_
virtual bool is_supported(const HierarchyContext *context) const override
USDLightWriter(const USDExporterContext &ctx)
virtual void do_write(HierarchyContext &context) override
EvaluationStage stage
Definition: deg_eval.cc:89
float r
float energy
float spec_fac
float area_sizey
short area_shape
float g
float area_size
float b
short type