Browse Source

exception for no-bone-weight vertex, fix bone weight normalize bug

Jason0214 7 years ago
parent
commit
30844aec43

+ 2 - 5
io_scene_godot/__init__.py

@@ -21,8 +21,9 @@ without significant importing (it's the same as Godot's tscn format).
 
 import bpy
 from bpy.props import StringProperty, BoolProperty, FloatProperty, EnumProperty
-
 from bpy_extras.io_utils import ExportHelper
+from .structures import ValidationError
+
 bl_info = {  # pylint: disable=invalid-name
     "name": "Godot Engine Exporter",
     "author": "Juan Linietsky",
@@ -39,10 +40,6 @@ bl_info = {  # pylint: disable=invalid-name
 }
 
 
-class ValidationError(Exception):
-    """An error type for explicitly delivering error messages to user."""
-
-
 class ExportGodot(bpy.types.Operator, ExportHelper):
     """Selection to Godot"""
     bl_idname = "export_godot.escn"

+ 20 - 12
io_scene_godot/converters/mesh.py

@@ -4,7 +4,8 @@ import bmesh
 import mathutils
 
 from .material import export_material
-from ..structures import Array, NodeTemplate, InternalResource, NodePath
+from ..structures import (Array, NodeTemplate, InternalResource, NodePath,
+                          ValidationError)
 from . import physics
 from . import armature
 
@@ -351,18 +352,25 @@ class Surface:
 
             weights = sorted(weights, key=lambda x: x[1], reverse=True)
             totalw = 0.0
-            for weight in weights:
+            for index, weight in enumerate(weights):
+                if index >= MAX_BONE_PER_VERTEX:
+                    break
                 totalw += weight[1]
-            if totalw == 0.0:
-                totalw = 0.000000001
-
-            for i in range(MAX_BONE_PER_VERTEX):
-                if i < len(weights):
-                    bone_idx_array.append(weights[i][0])
-                    bone_ws_array.append(weights[i][1]/totalw)
-                else:
-                    bone_idx_array.append(0)
-                    bone_ws_array.append(0.0)
+
+            if totalw > 0.0:
+                for i in range(MAX_BONE_PER_VERTEX):
+                    if i < len(weights):
+                        bone_idx_array.append(weights[i][0])
+                        bone_ws_array.append(weights[i][1]/totalw)
+                    else:
+                        bone_idx_array.append(0)
+                        bone_ws_array.append(0.0)
+            else:
+                # vertex not assign to any bones
+                raise ValidationError(
+                    "There are vertices with no bone weight in rigged mesh, "
+                    "please fix them in Blender"
+                )
 
         return bone_idx_array, bone_ws_array
 

+ 3 - 2
io_scene_godot/export_godot.py

@@ -38,7 +38,6 @@ logging.basicConfig(level=logging.INFO, format="[%(levelname)s]: %(message)s")
 def find_godot_project_dir(export_path):
     """Finds the project.godot file assuming that the export path
     is inside a project (looks for a project.godot file)"""
-    from . import ValidationError
     project_dir = export_path
 
     # Search up until we get to the top, which is "/" in *nix.
@@ -48,7 +47,9 @@ def find_godot_project_dir(export_path):
     while not os.path.isfile(os.path.join(project_dir, "project.godot")):
         project_dir = os.path.split(project_dir)[0]
         if project_dir == "/" or project_dir == last:
-            raise ValidationError("Unable to find godot project file")
+            raise structures.ValidationError(
+                "Unable to find godot project file"
+            )
         last = project_dir
     logging.info("Found godot project directory at %s", project_dir)
     return project_dir

+ 4 - 0
io_scene_godot/structures.py

@@ -7,6 +7,10 @@ import collections
 import mathutils
 
 
+class ValidationError(Exception):
+    """An error type for explicitly delivering error messages to user."""
+
+
 class ESCNFile:
     """The ESCN file consists of three major sections:
      - paths to external resources