diff options
author | Julien Duroure <julien.duroure@gmail.com> | 2019-02-22 20:34:02 +0300 |
---|---|---|
committer | Julien Duroure <julien.duroure@gmail.com> | 2019-02-22 20:34:02 +0300 |
commit | 14c202c04cd225192f23d1ea61d5b1dd8c76e266 (patch) | |
tree | a3b840f32f097cdd5e7d0ed1a41a4f1207ecb4c3 /io_scene_gltf2 | |
parent | 26330ab14347cef00d67e2e4335c9609082e227b (diff) |
glTF exporter: Fix texture transform conversion
Diffstat (limited to 'io_scene_gltf2')
-rwxr-xr-x | io_scene_gltf2/blender/com/gltf2_blender_conversion.py | 29 | ||||
-rwxr-xr-x | io_scene_gltf2/blender/exp/gltf2_blender_get.py | 67 |
2 files changed, 78 insertions, 18 deletions
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_conversion.py b/io_scene_gltf2/blender/com/gltf2_blender_conversion.py index 7adb3c9b..81340b3d 100755 --- a/io_scene_gltf2/blender/com/gltf2_blender_conversion.py +++ b/io_scene_gltf2/blender/com/gltf2_blender_conversion.py @@ -47,22 +47,37 @@ def correction_rotation(): # and lamps has no vertices :) return Quaternion((sqrt(2)/2, -sqrt(2)/2, 0.0, 0.0)).to_matrix().to_4x4() -def convert_texture_transform(texture_transform): +def texture_transform_blender_to_gltf(mapping_transform): """ - Converts a KHR_texture_transform object in one UV space (glTF or Blender) - into the equivalent in the other UV space. The returned transform is the - same as switching UV spaces (with u,v -> u,1-v), applying texture_transform, - then switching back. + Converts the offset/rotation/scale from a Mapping node applied in Blender's + UV space to the equivalent KHR_texture_transform. + """ + offset = mapping_transform.get('offset', [0, 0]) + rotation = mapping_transform.get('rotation', 0) + scale = mapping_transform.get('scale', [1, 1]) + return { + 'offset': [ + offset[0] - scale[1] * sin(rotation), + 1 - offset[1] - scale[1] * cos(rotation), + ], + 'rotation': rotation, + 'scale': [scale[0], scale[1]], + } + +def texture_transform_gltf_to_blender(texture_transform): + """ + Converts a KHR_texture_transform into the equivalent offset/rotation/scale + for a Mapping node applied in Blender's UV space. """ offset = texture_transform.get('offset', [0, 0]) rotation = texture_transform.get('rotation', 0) scale = texture_transform.get('scale', [1, 1]) return { 'offset': [ - offset[0] - scale[1] * sin(rotation), + offset[0] + scale[1] * sin(rotation), 1 - offset[1] - scale[1] * cos(rotation), ], - 'rotation': -rotation, + 'rotation': rotation, 'scale': [scale[0], scale[1]], } diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_get.py b/io_scene_gltf2/blender/exp/gltf2_blender_get.py index 3e604bb7..a40d9655 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_get.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_get.py @@ -17,10 +17,11 @@ # import bpy +from mathutils import Vector, Matrix from . import gltf2_blender_export_keys from ...io.exp import gltf2_io_get -from ...blender.com.gltf2_blender_conversion import convert_texture_transform +from ...blender.com.gltf2_blender_conversion import texture_transform_blender_to_gltf from io_scene_gltf2.io.com import gltf2_io_debug # # Globals @@ -356,17 +357,61 @@ def get_texture_transform_from_texture_node(texture_node): if not isinstance(mapping_node, bpy.types.ShaderNodeMapping): return None - texture_transform = {} - if mapping_node.vector_type == 'TEXTURE': - texture_transform["offset"] = [-mapping_node.translation[0], -mapping_node.translation[1]] - texture_transform["rotation"] = -mapping_node.rotation[2] - texture_transform["scale"] = [1.0 / mapping_node.scale[0], 1.0 / mapping_node.scale[1]] - elif mapping_node.vector_type == 'POINT': - texture_transform["offset"] = [mapping_node.translation[0], mapping_node.translation[1]] - texture_transform["rotation"] = mapping_node.rotation[2] - texture_transform["scale"] = [mapping_node.scale[0], mapping_node.scale[1]] + if mapping_node.vector_type not in ["TEXTURE", "POINT", "VECTOR"]: + gltf2_io_debug.print_console("WARNING", + "Skipping exporting texture transform because it had type " + + mapping_node.vector_type + "; recommend using POINT instead" + ) + return None + + if mapping_node.rotation[0] or mapping_node.rotation[1]: + # TODO: can we handle this? + gltf2_io_debug.print_console("WARNING", + "Skipping exporting texture transform because it had non-zero " + "rotations in the X/Y direction; only a Z rotation can be exported!" + ) + return None + + mapping_transform = {} + mapping_transform["offset"] = [mapping_node.translation[0], mapping_node.translation[1]] + mapping_transform["rotation"] = mapping_node.rotation[2] + mapping_transform["scale"] = [mapping_node.scale[0], mapping_node.scale[1]] + + if mapping_node.vector_type == "TEXTURE": + # This means use the inverse of the TRS transform. + def inverted(mapping_transform): + offset = mapping_transform["offset"] + rotation = mapping_transform["rotation"] + scale = mapping_transform["scale"] + + # Inverse of a TRS is not always a TRS. This function will be right + # at least when the following don't occur. + if abs(rotation) > 1e-5 and abs(scale[0] - scale[1]) > 1e-5: + return None + if abs(scale[0]) < 1e-5 or abs(scale[1]) < 1e-5: + return None + + new_offset = Matrix.Rotation(-rotation, 3, 'Z') * Vector((-offset[0], -offset[1], 1)) + new_offset[0] /= scale[0]; new_offset[1] /= scale[1] + return { + "offset": new_offset[0:2], + "rotation": -rotation, + "scale": [1/scale[0], 1/scale[1]], + } + + mapping_transform = inverted(mapping_transform) + if mapping_transform is None: + gltf2_io_debug.print_console("WARNING", + "Skipping exporting texture transform with type TEXTURE because " + "we couldn't convert it to TRS; recommend using POINT instead" + ) + return None + + elif mapping_node.vector_type == "VECTOR": + # Vectors don't get translated + mapping_transform["offset"] = [0, 0] - texture_transform = convert_texture_transform(texture_transform) + texture_transform = texture_transform_blender_to_gltf(mapping_transform) if all([component == 0 for component in texture_transform["offset"]]): del(texture_transform["offset"]) |