[Bf-extensions-cvs] [14c202c0] master: glTF exporter: Fix texture transform conversion

Julien Duroure noreply at git.blender.org
Fri Feb 22 18:34:35 CET 2019


Commit: 14c202c04cd225192f23d1ea61d5b1dd8c76e266
Author: Julien Duroure
Date:   Fri Feb 22 18:34:02 2019 +0100
Branches: master
https://developer.blender.org/rBA14c202c04cd225192f23d1ea61d5b1dd8c76e266

glTF exporter: Fix texture transform conversion

===================================================================

M	io_scene_gltf2/blender/com/gltf2_blender_conversion.py
M	io_scene_gltf2/blender/exp/gltf2_blender_get.py

===================================================================

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"])



More information about the Bf-extensions-cvs mailing list