[Bf-extensions-cvs] [eb33af13] master: glTF exporter: Auto limit and normalize skin weights

Julien Duroure noreply at git.blender.org
Thu Feb 14 21:21:39 CET 2019


Commit: eb33af1379355b9e1f85ff136a83306097ebc4f5
Author: Julien Duroure
Date:   Thu Feb 14 21:21:11 2019 +0100
Branches: master
https://developer.blender.org/rBAeb33af1379355b9e1f85ff136a83306097ebc4f5

glTF exporter: Auto limit and normalize skin weights

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

M	io_scene_gltf2/blender/exp/gltf2_blender_extract.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py

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

diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index fb3c714b..cd58367d 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -18,6 +18,7 @@
 
 from mathutils import Vector, Quaternion
 from mathutils.geometry import tessellate_polygon
+from operator import attrgetter
 
 from . import gltf2_blender_export_keys
 from ...io.com.gltf2_io_debug import print_console
@@ -639,7 +640,11 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
             if blender_vertex_groups is not None and vertex.groups is not None and len(vertex.groups) > 0 and export_settings[gltf2_blender_export_keys.SKINS]:
                 joint = []
                 weight = []
-                for group_element in vertex.groups:
+                vertex_groups = vertex.groups
+                if not export_settings['gltf_all_vertex_influences']:
+                    # sort groups by weight descending
+                    vertex_groups = sorted(vertex.groups, key=attrgetter('weight'), reverse=True)
+                for group_element in vertex_groups:
 
                     if len(joint) == 4:
                         bone_count += 1
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
index 76a1f0e4..96b3e4fc 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
@@ -161,14 +161,14 @@ def __gather_colors(blender_primitive, export_settings):
 def __gather_skins(blender_primitive, export_settings):
     attributes = {}
     if export_settings[gltf2_blender_export_keys.SKINS]:
-        bone_index = 0
-        joint_id = 'JOINTS_' + str(bone_index)
-        weight_id = 'WEIGHTS_' + str(bone_index)
+        bone_set_index = 0
+        joint_id = 'JOINTS_' + str(bone_set_index)
+        weight_id = 'WEIGHTS_' + str(bone_set_index)
         while blender_primitive["attributes"].get(joint_id) and blender_primitive["attributes"].get(weight_id):
-            if bone_index >= 4:
-                gltf2_io_debug.print_console("WARNING", "There are more than 4 joint vertex influences."
-                                                        "Consider to apply blenders Limit Total function.")
+            if bone_set_index >= 1:
                 if not export_settings['gltf_all_vertex_influences']:
+                    gltf2_io_debug.print_console("WARNING", "There are more than 4 joint vertex influences."
+                                                            "The 4 with highest weight will be used (and normalized).")
                     break
 
             # joints
@@ -192,6 +192,15 @@ def __gather_skins(blender_primitive, export_settings):
 
             # weights
             internal_weight = blender_primitive["attributes"][weight_id]
+            # normalize first 4 weights, when not exporting all influences
+            if not export_settings['gltf_all_vertex_influences']:
+                for idx in range(0, len(internal_weight), 4):
+                    weight_slice = internal_weight[idx:idx + 4]
+                    total = sum(weight_slice)
+                    if total > 0:
+                        factor = 1.0 / total
+                        internal_weight[idx:idx + 4] = [w * factor for w in weight_slice]
+
             weight = gltf2_io.Accessor(
                 buffer_view=gltf2_io_binary_data.BinaryData.from_list(
                     internal_weight, gltf2_io_constants.ComponentType.Float),
@@ -210,8 +219,8 @@ def __gather_skins(blender_primitive, export_settings):
             )
             attributes[weight_id] = weight
 
-            bone_index += 1
-            joint_id = 'JOINTS_' + str(bone_index)
-            weight_id = 'WEIGHTS_' + str(bone_index)
+            bone_set_index += 1
+            joint_id = 'JOINTS_' + str(bone_set_index)
+            weight_id = 'WEIGHTS_' + str(bone_set_index)
     return attributes



More information about the Bf-extensions-cvs mailing list