diff options
author | Julien Duroure <julien.duroure@gmail.com> | 2018-12-19 23:18:23 +0300 |
---|---|---|
committer | Julien Duroure <julien.duroure@gmail.com> | 2018-12-19 23:18:23 +0300 |
commit | 9c914cb37526bd8c080e84886d70e582618cc128 (patch) | |
tree | af78cf5c3a3ee9d5713dd561e1f282a5d7bd5495 /io_scene_gltf2/blender | |
parent | 6a1ce20043860e4f836294d46a86b5fcf7fbf1a8 (diff) |
glTF import: add support of KHR_lights_punctual extension
Diffstat (limited to 'io_scene_gltf2/blender')
5 files changed, 135 insertions, 5 deletions
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_conversion.py b/io_scene_gltf2/blender/com/gltf2_blender_conversion.py index 95fa292d..adc797ee 100755 --- a/io_scene_gltf2/blender/com/gltf2_blender_conversion.py +++ b/io_scene_gltf2/blender/com/gltf2_blender_conversion.py @@ -13,6 +13,7 @@ # limitations under the License. from mathutils import Matrix, Quaternion +from math import sqrt def matrix_gltf_to_blender(mat_input): """Matrix from glTF format to Blender format.""" @@ -40,3 +41,9 @@ def scale_to_matrix(scale): return mat +def correction_rotation(): + """Correction of Rotation.""" + # Correction is needed for lamps, because Yup2Zup is not written in vertices + # and lamps has no vertices :) + return Quaternion((sqrt(2)/2, -sqrt(2)/2, 0.0, 0.0)).to_matrix().to_4x4() + diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py index c053f84a..60947c1f 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py @@ -16,6 +16,7 @@ import bpy from mathutils import Vector from ..com.gltf2_blender_conversion import loc_gltf_to_blender, quaternion_gltf_to_blender, scale_gltf_to_blender +from ..com.gltf2_blender_conversion import correction_rotation from ...io.imp.gltf2_io_binary import BinaryData @@ -96,9 +97,15 @@ class BlenderNodeAnim(): for idx, key in enumerate(keys): if animation.samplers[channel.sampler].interpolation == "CUBICSPLINE": # TODO manage tangent? - obj.rotation_quaternion = quaternion_gltf_to_blender(values[idx * 3 + 1]) + vals = values[idx * 3 + 1] else: - obj.rotation_quaternion = quaternion_gltf_to_blender(values[idx]) + vals = values[idx] + + if node.correction_needed is True: + obj.rotation_quaternion = (quaternion_gltf_to_blender(vals).to_matrix().to_4x4() @ correction_rotation()).to_quaternion() + else: + obj.rotation_quaternion = quaternion_gltf_to_blender(vals) + obj.keyframe_insert(blender_path, frame=key[0] * fps, group='rotation') # Setting interpolation diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py index 1f708b40..e4cb65f1 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py @@ -169,6 +169,9 @@ class BlenderGlTF(): gltf.data.skins[node.skin].node_ids.append(node_idx) + # Lights management + node.correction_needed = False + # transform management if node.matrix: node.transform = node.matrix diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_light.py b/io_scene_gltf2/blender/imp/gltf2_blender_light.py new file mode 100644 index 00000000..5d7cb355 --- /dev/null +++ b/io_scene_gltf2/blender/imp/gltf2_blender_light.py @@ -0,0 +1,91 @@ +# Copyright 2018 The glTF-Blender-IO authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import bpy +from math import pi + + +class BlenderLight(): + """Blender Light.""" + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + @staticmethod + def create(gltf, light_id): + """Light creation.""" + pylight = gltf.data.extensions['KHR_lights_punctual']['lights'][light_id] + if pylight['type'] == "directional": + obj = BlenderLight.create_directional(gltf, light_id) + elif pylight['type'] == "point": + obj = BlenderLight.create_point(gltf, light_id) + elif pylight['type'] == "spot": + obj = BlenderLight.create_spot(gltf, light_id) + + if 'color' in pylight.keys(): + obj.data.color = pylight['color'] + + if 'intensity' in pylight.keys(): + obj.data.energy = pylight['intensity'] + + # TODO range + + bpy.data.scenes[gltf.blender_scene].collection.objects.link(obj) + + return obj + + @staticmethod + def create_directional(gltf, light_id): + pylight = gltf.data.extensions['KHR_lights_punctual']['lights'][light_id] + + if 'name' not in pylight.keys(): + pylight['name'] = "Sun" + + sun = bpy.data.lights.new(name=pylight['name'], type="SUN") + obj = bpy.data.objects.new(pylight['name'], sun) + return obj + + @staticmethod + def create_point(gltf, light_id): + pylight = gltf.data.extensions['KHR_lights_punctual']['lights'][light_id] + + if 'name' not in pylight.keys(): + pylight['name'] = "Point" + + point = bpy.data.lights.new(name=pylight['name'], type="POINT") + obj = bpy.data.objects.new(pylight['name'], point) + return obj + + @staticmethod + def create_spot(gltf, light_id): + pylight = gltf.data.extensions['KHR_lights_punctual']['lights'][light_id] + + if 'name' not in pylight.keys(): + pylight['name'] = "Spot" + + spot = bpy.data.lights.new(name=pylight['name'], type="SPOT") + obj = bpy.data.objects.new(pylight['name'], spot) + + # Angles + if 'spot' in pylight.keys() and 'outerConeAngle' in pylight['spot']: + spot.spot_size = pylight['spot']['outerConeAngle'] * 2 + else: + spot.spot_size = pi / 2 + + if 'spot' in pylight.keys() and 'innerConeAngle' in pylight['spot']: + spot.spot_blend = 1 - ( pylight['spot']['innerConeAngle'] / pylight['spot']['outerConeAngle'] ) + else: + spot.spot_blend = 1.0 + + return obj + diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_node.py index a82f1db7..0e49e28b 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_node.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_node.py @@ -16,7 +16,8 @@ import bpy from .gltf2_blender_mesh import BlenderMesh from .gltf2_blender_camera import BlenderCamera from .gltf2_blender_skin import BlenderSkin -from ..com.gltf2_blender_conversion import scale_to_matrix, matrix_gltf_to_blender +from .gltf2_blender_light import BlenderLight +from ..com.gltf2_blender_conversion import scale_to_matrix, matrix_gltf_to_blender, correction_rotation class BlenderNode(): @@ -103,7 +104,22 @@ class BlenderNode(): return - # No mesh, no camera. For now, create empty #TODO + if pynode.extensions is not None: + if 'KHR_lights_punctual' in pynode.extensions.keys(): + obj = BlenderLight.create(gltf, pynode.extensions['KHR_lights_punctual']['light']) + obj.rotation_mode = 'QUATERNION' + BlenderNode.set_transforms(gltf, node_idx, pynode, obj, parent, correction=True) + pynode.blender_object = obj.name + pynode.correction_needed = True + BlenderNode.set_parent(gltf, pynode, obj, parent) + + if pynode.children: + for child_idx in pynode.children: + BlenderNode.create(gltf, child_idx, node_idx) + + return + + # No mesh, no camera, no light. For now, create empty #TODO if pynode.name: gltf.log.info("Blender create Empty node " + pynode.name) @@ -167,18 +183,24 @@ class BlenderNode(): gltf.log.error("ERROR, parent not found") @staticmethod - def set_transforms(gltf, node_idx, pynode, obj, parent): + def set_transforms(gltf, node_idx, pynode, obj, parent, correction=False): """Set transforms.""" if parent is None: obj.matrix_world = matrix_gltf_to_blender(pynode.transform) + if correction is True: + obj.matrix_world = obj.matrix_world @ correction_rotation() return for idx, node in enumerate(gltf.data.nodes): if idx == parent: if node.is_joint is True: obj.matrix_world = matrix_gltf_to_blender(pynode.transform) + if correction is True: + obj.matrix_world = obj.matrix_world @ correction_rotation() return else: + if correction is True: + obj.matrix_world = obj.matrix_world @ correction_rotation() obj.matrix_world = matrix_gltf_to_blender(pynode.transform) return |