1 # SPDX-FileCopyrightText: 2018-2021 The glTF-Blender-IO authors
3 # SPDX-License-Identifier: Apache-2.0
8 from ...io
.imp
.gltf2_io_user_extensions
import import_user_extensions
9 from ..com
.gltf2_blender_conversion
import PBR_WATTS_TO_LUMENS
10 from ..com
.gltf2_blender_extras
import set_extras
14 def __new__(cls
, *args
, **kwargs
):
15 raise RuntimeError("%s should not be instantiated" % cls
)
18 def create(gltf
, vnode
, light_id
):
20 pylight
= gltf
.data
.extensions
['KHR_lights_punctual']['lights'][light_id
]
22 import_user_extensions('gather_import_light_before_hook', gltf
, vnode
, pylight
)
24 if pylight
['type'] == "directional":
25 light
= BlenderLight
.create_directional(gltf
, light_id
) # ...Why not pass the pylight?
26 elif pylight
['type'] == "point":
27 light
= BlenderLight
.create_point(gltf
, light_id
)
28 elif pylight
['type'] == "spot":
29 light
= BlenderLight
.create_spot(gltf
, light_id
)
31 if 'color' in pylight
.keys():
32 light
.color
= pylight
['color']
36 set_extras(light
, pylight
.get('extras'))
38 pylight
['blender_object_data'] = light
# Needed in case of KHR_animation_pointer
43 def create_directional(gltf
, light_id
):
44 pylight
= gltf
.data
.extensions
['KHR_lights_punctual']['lights'][light_id
]
46 if 'name' not in pylight
.keys():
47 pylight
['name'] = "Sun" # Uh... Is it okay to mutate the import data?
49 sun
= bpy
.data
.lights
.new(name
=pylight
['name'], type="SUN")
51 if 'intensity' in pylight
.keys():
52 sun
.energy
= BlenderLight
.calc_energy_directional(gltf
, pylight
['intensity'])
57 def calc_energy_directional(gltf
, pylight_data
):
58 if gltf
.import_settings
['export_import_convert_lighting_mode'] == 'SPEC':
59 return pylight_data
/ PBR_WATTS_TO_LUMENS
60 elif gltf
.import_settings
['export_import_convert_lighting_mode'] == 'COMPAT':
62 elif gltf
.import_settings
['export_import_convert_lighting_mode'] == 'RAW':
65 raise ValueError(gltf
.import_settings
['export_import_convert_lighting_mode'])
68 def calc_energy_pointlike(gltf
, pylight_data
):
69 if gltf
.import_settings
['export_import_convert_lighting_mode'] == 'SPEC':
70 return pylight_data
/ PBR_WATTS_TO_LUMENS
* 4 * pi
71 elif gltf
.import_settings
['export_import_convert_lighting_mode'] == 'COMPAT':
72 return pylight_data
* 4 * pi
73 elif gltf
.import_settings
['export_import_convert_lighting_mode'] == 'RAW':
76 raise ValueError(gltf
.import_settings
['export_import_convert_lighting_mode'])
79 def create_point(gltf
, light_id
):
80 pylight
= gltf
.data
.extensions
['KHR_lights_punctual']['lights'][light_id
]
82 if 'name' not in pylight
.keys():
83 pylight
['name'] = "Point"
85 point
= bpy
.data
.lights
.new(name
=pylight
['name'], type="POINT")
87 if 'intensity' in pylight
.keys():
88 point
.energy
= BlenderLight
.calc_energy_pointlike(gltf
, pylight
['intensity'])
93 def create_spot(gltf
, light_id
):
94 pylight
= gltf
.data
.extensions
['KHR_lights_punctual']['lights'][light_id
]
96 if 'name' not in pylight
.keys():
97 pylight
['name'] = "Spot"
99 spot
= bpy
.data
.lights
.new(name
=pylight
['name'], type="SPOT")
102 if 'spot' in pylight
.keys() and 'outerConeAngle' in pylight
['spot']:
103 spot
.spot_size
= BlenderLight
.calc_spot_cone_outer(gltf
, pylight
['spot']['outerConeAngle'])
105 spot
.spot_size
= pi
/ 2
107 if 'spot' in pylight
.keys() and 'innerConeAngle' in pylight
['spot']:
108 spot
.spot_blend
= BlenderLight
.calc_spot_cone_inner(gltf
, pylight
['spot']['outerConeAngle'], pylight
['spot']['innerConeAngle'])
110 spot
.spot_blend
= 1.0
112 if 'intensity' in pylight
.keys():
113 spot
.energy
= BlenderLight
.calc_energy_pointlike(gltf
, pylight
['intensity'])
115 # Store multiple channel data, as we will need all channels to convert to blender data when animated by KHR_animation_pointer
116 if gltf
.data
.extensions_used
is not None and "KHR_animation_pointer" in gltf
.data
.extensions_used
:
117 if len(pylight
['animations']) > 0:
118 for anim_idx
in pylight
['animations'].keys():
119 for channel_idx
in pylight
['animations'][anim_idx
]:
120 channel
= gltf
.data
.animations
[anim_idx
].channels
[channel_idx
]
121 pointer_tab
= channel
.target
.extensions
["KHR_animation_pointer"]["pointer"].split("/")
122 if len(pointer_tab
) == 6 and pointer_tab
[1] == "extensions" and \
123 pointer_tab
[2] == "KHR_lights_punctual" and \
124 pointer_tab
[3] == "lights" and \
125 pointer_tab
[5] in ["spot.innerConeAngle", "spot.outerConeAngle"]:
126 # Store multiple channel data, as we will need all channels to convert to blender data when animated
127 if "multiple_channels" not in pylight
.keys():
128 pylight
['multiple_channels'] = {}
129 pylight
['multiple_channels'][pointer_tab
[5]] = (anim_idx
, channel_idx
)
134 def calc_spot_cone_outer(gltf
, outercone
):
138 def calc_spot_cone_inner(gltf
, outercone
, innercone
):
139 return 1 - ( innercone
/ outercone
)