glTF importer: add "Fortune" bone heuristic

The "Fortune" bone heuristic helps bones look better in files where their local axes are weird, but in exchange may be inaccurate when a bone has a non-uniform scaling.
This commit is contained in:
Julien Duroure 2020-03-27 18:37:14 +01:00
parent 2425a37ae5
commit 38531bbfa5
2 changed files with 17 additions and 8 deletions

View File

@ -15,7 +15,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (1, 2, 52),
"version": (1, 2, 53),
'blender': (2, 82, 7),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
@ -859,12 +859,17 @@ class ImportGLTF2(Operator, ImportHelper):
bone_heuristic: EnumProperty(
name="Bone Dir",
items=(
("BLENDER", "Blender (+Y)",
"Round-trips bone directions in glTFs exported from Blender.\n"
("BLENDER", "Blender (best for re-importing)",
"Good for re-importing glTFs exported from Blender.\n"
"Bone tips are placed on their local +Y axis (in glTF space)"),
("TEMPERANCE", "Temperance",
"Okay for many different models.\n"
"Bone tips are placed at a child's root")
("TEMPERANCE", "Temperance (average)",
"Decent all-around strategy.\n"
"A bone with one child has its tip placed on the local axis\n"
"closest to its child"),
("FORTUNE", "Fortune (may look better, less accurate)",
"Might look better than Temperance, but also might have errors.\n"
"A bone with one child has its tip placed at its child's root.\n"
"Non-uniform scalings may get messed up though, so beware"),
),
description="Heuristic for placing bones. Tries to make bones pretty",
default="TEMPERANCE",

View File

@ -459,7 +459,7 @@ def pick_bone_rotation(gltf, bone_id, parent_rot):
if gltf.import_settings['bone_heuristic'] == 'BLENDER':
return Quaternion((2**0.5/2, 2**0.5/2, 0, 0))
elif gltf.import_settings['bone_heuristic'] == 'TEMPERANCE':
elif gltf.import_settings['bone_heuristic'] in ['TEMPERANCE', 'FORTUNE']:
return temperance(gltf, bone_id, parent_rot)
def temperance(gltf, bone_id, parent_rot):
@ -475,7 +475,11 @@ def temperance(gltf, bone_id, parent_rot):
if child_locs:
centroid = sum(child_locs, Vector((0, 0, 0)))
rot = Vector((0, 1, 0)).rotation_difference(centroid)
rot = nearby_signed_perm_matrix(rot).to_quaternion()
if gltf.import_settings['bone_heuristic'] == 'TEMPERANCE':
# Snap to the local axes; required for local_rotation to be
# accurate when vnode has a non-uniform scaling.
# FORTUNE skips this, so it may look better, but may have errors.
rot = nearby_signed_perm_matrix(rot).to_quaternion()
return rot
return parent_rot