FBX export: yet another attempt to fix scaling issues...

Still have the feeling many apps do not use UnitScaleFactor prop correctly, though. :/
This commit is contained in:
Bastien Montagne 2014-10-07 15:20:35 +02:00
parent 36a8b39da3
commit cb581b0533
3 changed files with 8 additions and 4 deletions

View File

@ -186,7 +186,7 @@ class ImportFBX_experimental(bpy.types.Operator, ImportHelper):
sub.enabled = self.use_manual_orientation
sub.prop(self, "axis_forward")
sub.prop(self, "axis_up")
sub.prop(self, "global_scale")
layout.prop(self, "global_scale")
layout.prop(self, "bake_space_transform")
layout.prop(self, "use_image_search")

View File

@ -2537,7 +2537,6 @@ def fbx_header_elements(root, scene_data, time=None):
up_axis, front_axis, coord_axis = RIGHT_HAND_AXES[scene_data.settings.to_axes]
# Currently not sure about that, but looks like default unit of FBX is cm...
scale_factor = (1.0 if scene.unit_settings.system == 'NONE' else scene.unit_settings.scale_length) * 100
scale_factor /= scene_data.settings.global_scale
elem_props_set(props, "p_integer", b"UpAxis", up_axis[0])
elem_props_set(props, "p_integer", b"UpAxisSign", up_axis[1])
elem_props_set(props, "p_integer", b"FrontAxis", front_axis[0])
@ -2736,6 +2735,11 @@ def save_single(operator, scene, filepath="",
if 'OTHER' in object_types:
object_types |= BLENDER_OTHER_OBJECT_TYPES
# Scale/unit mess. FBX can store the 'reference' unit of a file in its UnitScaleFactor property
# (1.0 meaning centimeter, afaik). We use that to reflect user's default unit as set in Blender with scale_length.
# However, we always get values in BU (i.e. meters), so we have to reverse-apply that scale in global matrix...
if scene.unit_settings.system != 'NONE':
global_matrix *= (1.0 / scene.unit_settings.scale_length)
global_scale = global_matrix.median_scale
global_matrix_inv = global_matrix.inverted()
# For transforming mesh normals.

View File

@ -1920,6 +1920,8 @@ def load(operator, context, filepath="",
operator.report({'ERROR'}, "No 'GlobalSettings' found in file %r" % filepath)
return {'CANCELLED'}
# FBX default base unit seems to be the centimeter, while raw Blender Unit is equivalent to the meter...
global_scale *= elem_props_get_number(fbx_settings_props, b'UnitScaleFactor', 100.0) / 100.0
# Compute global matrix and scale.
if not use_manual_orientation:
axis_forward = (elem_props_get_integer(fbx_settings_props, b'FrontAxis', 1),
@ -1930,8 +1932,6 @@ def load(operator, context, filepath="",
elem_props_get_integer(fbx_settings_props, b'CoordAxisSign', 1))
axis_key = (axis_up, axis_forward, axis_coord)
axis_up, axis_forward = {v: k for k, v in RIGHT_HAND_AXES.items()}.get(axis_key, ('Z', 'Y'))
# FBX base unit seems to be the centimeter, while raw Blender Unit is equivalent to the meter...
global_scale = elem_props_get_number(fbx_settings_props, b'UnitScaleFactor', 100.0) / 100.0
global_matrix = (Matrix.Scale(global_scale, 4) *
axis_conversion(from_forward=axis_forward, from_up=axis_up).to_4x4())