Blender V4.3
io/usd/hydra/light.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "light.hh"
6
7#include <pxr/imaging/hd/light.h>
8#include <pxr/imaging/hd/tokens.h>
9#include <pxr/usd/usdLux/tokens.h>
10
11#include "DNA_light_types.h"
12
13#include "BLI_math_rotation.h"
14
16
17namespace blender::io::hydra {
18
20 const Object *object,
21 pxr::SdfPath const &prim_id)
22 : ObjectData(scene_delegate, object, prim_id)
23{
24}
25
27{
28 ID_LOGN(1, "");
29
30 const Light *light = (const Light *)((const Object *)id)->data;
31 data_.clear();
32
33 switch (light->type) {
34 case LA_AREA: {
35 switch (light->area_shape) {
36 case LA_AREA_SQUARE:
37 data_[pxr::HdLightTokens->width] = light->area_size;
38 data_[pxr::HdLightTokens->height] = light->area_size;
39 break;
40 case LA_AREA_RECT:
41 data_[pxr::HdLightTokens->width] = light->area_size;
42 data_[pxr::HdLightTokens->height] = light->area_sizey;
43 break;
44 case LA_AREA_DISK:
45 data_[pxr::HdLightTokens->radius] = light->area_size / 2.0f;
46 break;
47 case LA_AREA_ELLIPSE:
48 /* An ellipse light deteriorates into a disk light. */
49 data_[pxr::HdLightTokens->radius] = (light->area_size + light->area_sizey) / 4.0f;
50 break;
51 }
52 break;
53 }
54 case LA_LOCAL:
55 case LA_SPOT: {
56 data_[pxr::HdLightTokens->radius] = light->radius;
57 if (light->radius == 0.0f) {
58 data_[pxr::UsdLuxTokens->treatAsPoint] = true;
59 }
60
61 if (light->type == LA_SPOT) {
62 data_[pxr::UsdLuxTokens->inputsShapingConeAngle] = RAD2DEGF(light->spotsize * 0.5f);
63 data_[pxr::UsdLuxTokens->inputsShapingConeSoftness] = light->spotblend;
64 }
65 break;
66 }
67 case LA_SUN: {
68 data_[pxr::HdLightTokens->angle] = RAD2DEGF(light->sun_angle * 0.5f);
69 break;
70 }
71 default: {
73 break;
74 }
75 }
76
77 float intensity;
78 if (light->type == LA_SUN) {
79 /* Unclear why, but approximately matches Karma. */
80 intensity = light->energy / 4.0f;
81 }
82 else {
83 /* Convert from radiant flux to intensity. */
84 intensity = light->energy / M_PI;
85 }
86
87 data_[pxr::HdLightTokens->intensity] = intensity;
88 data_[pxr::HdLightTokens->exposure] = 0.0f;
89 data_[pxr::HdLightTokens->color] = pxr::GfVec3f(light->r, light->g, light->b);
90 data_[pxr::HdLightTokens->diffuse] = light->diff_fac;
91 data_[pxr::HdLightTokens->specular] = light->spec_fac;
92 data_[pxr::HdLightTokens->normalize] = true;
93
94 prim_type_ = prim_type(light);
95
97}
98
100{
101 ID_LOGN(1, "");
102 scene_delegate_->GetRenderIndex().InsertSprim(prim_type_, scene_delegate_, prim_id);
103}
104
106{
107 ID_LOG(1, "");
108 scene_delegate_->GetRenderIndex().RemoveSprim(prim_type_, prim_id);
109}
110
112{
113 const Object *object = (const Object *)id;
114 const Light *light = (const Light *)object->data;
115 pxr::HdDirtyBits bits = pxr::HdLight::Clean;
116 if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY) {
117 if (prim_type(light) != prim_type_) {
118 remove();
119 init();
120 insert();
121 return;
122 }
123 init();
124 bits = pxr::HdLight::AllDirty;
125 }
126 else if (id->recalc & ID_RECALC_TRANSFORM) {
128 bits = pxr::HdLight::DirtyTransform;
129 }
130 if (bits != pxr::HdChangeTracker::Clean) {
131 scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits);
132 ID_LOGN(1, "");
133 }
134}
135
136pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
137{
138 ID_LOGN(3, "%s", key.GetText());
139 auto it = data_.find(key);
140 if (it != data_.end()) {
141 return pxr::VtValue(it->second);
142 }
143
144 return pxr::VtValue();
145}
146
147pxr::TfToken LightData::prim_type(const Light *light)
148{
149 switch (light->type) {
150 case LA_AREA:
151 switch (light->area_shape) {
152 case LA_AREA_SQUARE:
153 case LA_AREA_RECT:
154 return pxr::HdPrimTypeTokens->rectLight;
155
156 case LA_AREA_DISK:
157 case LA_AREA_ELLIPSE:
158 return pxr::HdPrimTypeTokens->diskLight;
159
160 default:
161 return pxr::HdPrimTypeTokens->rectLight;
162 }
163 break;
164
165 case LA_LOCAL:
166 case LA_SPOT:
167 return pxr::HdPrimTypeTokens->sphereLight;
168
169 case LA_SUN:
170 return pxr::HdPrimTypeTokens->distantLight;
171
172 default:
174 }
175 return pxr::TfToken();
176}
177
178} // namespace blender::io::hydra
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define M_PI
#define RAD2DEGF(_rad)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ LA_AREA
@ LA_LOCAL
@ LA_SPOT
@ LA_SUN
@ LA_AREA_ELLIPSE
@ LA_AREA_SQUARE
@ LA_AREA_RECT
@ LA_AREA_DISK
pxr::SdfPath prim_id
Definition id.hh:36
HydraSceneDelegate * scene_delegate_
Definition id.hh:39
pxr::TfToken prim_type(const Light *light)
LightData(HydraSceneDelegate *scene_delegate, const Object *object, pxr::SdfPath const &prim_id)
std::map< pxr::TfToken, pxr::VtValue > data_
Definition light.hh:23
pxr::VtValue get_data(pxr::TfToken const &key) const override
#define ID_LOG(level, msg,...)
Definition id.hh:53
#define ID_LOGN(level, msg,...)
Definition id.hh:56
float area_size