Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-05-18 18:58:12 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-05-18 18:58:12 +0300
commit91976e77c322b95fa29544a81dd46c3008facddd (patch)
tree57d0f40ce02651d9e98e8c62b9e6c6dad9743f90
parent717c062b5ed2237206c21b1bff9cc438f76ae358 (diff)
FBX export: more twisting and co to attempt fixing scale/animation issue, still failing.
-rw-r--r--io_scene_fbx/__init__.py2
-rw-r--r--io_scene_fbx/export_fbx_bin.py36
-rw-r--r--io_scene_fbx/fbx_utils.py39
3 files changed, 49 insertions, 28 deletions
diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 4038c2ae..1e644cdc 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "FBX format",
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
- "version": (3, 2, 5),
+ "version": (3, 2, 6),
"blender": (2, 74, 0),
"location": "File > Import-Export",
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index d757f3c7..12645594 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -712,7 +712,7 @@ def fbx_data_bindpose_element(root, me_obj, me, scene_data, arm_obj=None, mat_wo
elem_data_single_string(fbx_pose, b"Type", b"BindPose")
elem_data_single_int32(fbx_pose, b"Version", FBX_POSE_BIND_VERSION)
- elem_data_single_int32(fbx_pose, b"NbPoseNodes", 1 + len(bones))
+ elem_data_single_int32(fbx_pose, b"NbPoseNodes", 1 + (1 if (arm_obj != me_obj) else 0) + len(bones))
# First node is mesh/object.
mat_world_obj = me_obj.fbx_object_matrix(scene_data, global_space=True)
@@ -1508,6 +1508,7 @@ def fbx_data_leaf_bone_elements(root, scene_data):
tmpl = elem_props_template_init(scene_data.templates, b"Model")
# For now add only loc/rot/scale...
props = elem_properties(model)
+ # Generated leaf bones are obviously never animated!
elem_props_template_set(tmpl, props, "p_lcl_translation", b"Lcl Translation", loc)
elem_props_template_set(tmpl, props, "p_lcl_rotation", b"Lcl Rotation", rot)
elem_props_template_set(tmpl, props, "p_lcl_scaling", b"Lcl Scaling", scale)
@@ -1559,9 +1560,12 @@ def fbx_data_object_elements(root, ob_obj, scene_data):
tmpl = elem_props_template_init(scene_data.templates, b"Model")
# For now add only loc/rot/scale...
props = elem_properties(model)
- elem_props_template_set(tmpl, props, "p_lcl_translation", b"Lcl Translation", loc)
- elem_props_template_set(tmpl, props, "p_lcl_rotation", b"Lcl Rotation", rot)
- elem_props_template_set(tmpl, props, "p_lcl_scaling", b"Lcl Scaling", scale)
+ elem_props_template_set(tmpl, props, "p_lcl_translation", b"Lcl Translation", loc,
+ animatable=True, animated=((ob_obj.key, "Lcl Translation") in scene_data.animated))
+ elem_props_template_set(tmpl, props, "p_lcl_rotation", b"Lcl Rotation", rot,
+ animatable=True, animated=((ob_obj.key, "Lcl Rotation") in scene_data.animated))
+ elem_props_template_set(tmpl, props, "p_lcl_scaling", b"Lcl Scaling", scale,
+ animatable=True, animated=((ob_obj.key, "Lcl Scaling") in scene_data.animated))
elem_props_template_set(tmpl, props, "p_visibility", b"Visibility", float(not ob_obj.hide))
# Absolutely no idea what this is, but seems mandatory for validity of the file, and defaults to
@@ -1940,10 +1944,11 @@ def fbx_animations(scene_data):
"""
scene = scene_data.scene
animations = []
+ animated = set()
frame_start = 1e100
frame_end = -1e100
- def add_anim(animations, anim):
+ def add_anim(animations, animated, anim):
nonlocal frame_start, frame_end
if anim is not None:
animations.append(anim)
@@ -1953,6 +1958,11 @@ def fbx_animations(scene_data):
if f_end > frame_end:
frame_end = f_end
+ _astack_key, astack, _alayer_key, _name, _fstart, _fend = anim
+ for elem_key, (alayer_key, acurvenodes) in astack.items():
+ for fbx_prop, (acurvenode_key, acurves, acurvenode_name) in acurvenodes.items():
+ animated.add((elem_key, fbx_prop))
+
# Per-NLA strip animstacks.
if scene_data.settings.bake_anim_use_nla_strips:
strips = []
@@ -1974,7 +1984,8 @@ def fbx_animations(scene_data):
for strip in strips:
strip.mute = False
- add_anim(animations, fbx_animations_do(scene_data, strip, strip.frame_start, strip.frame_end, True))
+ add_anim(animations, animated,
+ fbx_animations_do(scene_data, strip, strip.frame_start, strip.frame_end, True))
strip.mute = True
for strip in strips:
@@ -2039,7 +2050,7 @@ def fbx_animations(scene_data):
continue
ob.animation_data.action = act
frame_start, frame_end = act.frame_range # sic!
- add_anim(animations,
+ add_anim(animations, animated,
fbx_animations_do(scene_data, (ob, act), frame_start, frame_end, True, {ob_obj}, True))
# Ugly! :/
if pbones_matrices is not ...:
@@ -2057,12 +2068,12 @@ def fbx_animations(scene_data):
# Global (containing everything) animstack, only if not exporting NLA strips and/or all actions.
if not scene_data.settings.bake_anim_use_nla_strips and not scene_data.settings.bake_anim_use_all_actions:
- add_anim(animations, fbx_animations_do(scene_data, None, scene.frame_start, scene.frame_end, False))
+ add_anim(animations, animated, fbx_animations_do(scene_data, None, scene.frame_start, scene.frame_end, False))
# Be sure to update all matrices back to org state!
scene.frame_set(scene.frame_current, 0.0)
- return animations, frame_start, frame_end
+ return animations, animated, frame_start, frame_end
def fbx_data_from_scene(scene, settings):
@@ -2259,6 +2270,7 @@ def fbx_data_from_scene(scene, settings):
# Animation...
animations = ()
+ animated = set()
frame_start = scene.frame_start
frame_end = scene.frame_end
if settings.bake_anim:
@@ -2266,12 +2278,12 @@ def fbx_data_from_scene(scene, settings):
# Kind of hack, we need a temp scene_data for object's space handling to bake animations...
tmp_scdata = FBXExportData(
None, None, None,
- settings, scene, objects, None, 0.0, 0.0,
+ settings, scene, objects, None, None, 0.0, 0.0,
data_empties, data_lamps, data_cameras, data_meshes, None,
data_bones, data_leaf_bones, data_deformers_skin, data_deformers_shape,
data_world, data_materials, data_textures, data_videos,
)
- animations, frame_start, frame_end = fbx_animations(tmp_scdata)
+ animations, animated, frame_start, frame_end = fbx_animations(tmp_scdata)
# ##### Creation of templates...
@@ -2484,7 +2496,7 @@ def fbx_data_from_scene(scene, settings):
return FBXExportData(
templates, templates_users, connections,
- settings, scene, objects, animations, frame_start, frame_end,
+ settings, scene, objects, animations, animated, frame_start, frame_end,
data_empties, data_lamps, data_cameras, data_meshes, mesh_mat_indices,
data_bones, data_leaf_bones, data_deformers_skin, data_deformers_shape,
data_world, data_materials, data_textures, data_videos,
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index 65ab2470..e6cab6b0 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -569,25 +569,33 @@ def _elem_props_set(elem, ptype, name, value, flags):
getattr(p, callback)(val)
-def _elem_props_flags(animatable, custom):
- if animatable and custom:
- return b"AU"
- elif animatable:
+def _elem_props_flags(animatable, animated, custom):
+ # XXX: There are way more flags, see
+ # http://help.autodesk.com/view/FBX/2015/ENU/?guid=__cpp_ref_class_fbx_property_flags_html
+ # Unfortunately, as usual, no doc at all about their 'translation' in actual FBX file format.
+ # Curse you-know-who.
+ if animatable:
+ if animated:
+ if custom:
+ return b"A+U"
+ return b"A+"
+ if custom:
+ return b"AU"
return b"A"
- elif custom:
+ if custom:
return b"U"
return b""
-def elem_props_set(elem, ptype, name, value=None, animatable=False, custom=False):
+def elem_props_set(elem, ptype, name, value=None, animatable=False, animated=False, custom=False):
ptype = FBX_PROPERTIES_DEFINITIONS[ptype]
- _elem_props_set(elem, ptype, name, value, _elem_props_flags(animatable, custom))
+ _elem_props_set(elem, ptype, name, value, _elem_props_flags(animatable, animated, custom))
def elem_props_compound(elem, cmpd_name, custom=False):
- def _setter(ptype, name, value, animatable=False, custom=False):
+ def _setter(ptype, name, value, animatable=False, animated=False, custom=False):
name = cmpd_name + b"|" + name
- elem_props_set(elem, ptype, name, value, animatable=animatable, custom=custom)
+ elem_props_set(elem, ptype, name, value, animatable=animatable, animated=animated, custom=custom)
elem_props_set(elem, "p_compound", cmpd_name, custom=custom)
return _setter
@@ -606,7 +614,7 @@ def elem_props_template_init(templates, template_type):
return ret
-def elem_props_template_set(template, elem, ptype_name, name, value, animatable=False):
+def elem_props_template_set(template, elem, ptype_name, name, value, animatable=False, animated=False):
"""
Only add a prop if the same value is not already defined in given template.
Note it is important to not give iterators as value, here!
@@ -616,15 +624,16 @@ def elem_props_template_set(template, elem, ptype_name, name, value, animatable=
value = tuple(value)
tmpl_val, tmpl_ptype, tmpl_animatable, tmpl_written = template.get(name, (None, None, False, False))
# Note animatable flag from template takes precedence over given one, if applicable.
- if tmpl_ptype is not None:
+ # However, animated properties are always written, since they cannot match their template!
+ if tmpl_ptype is not None and not animated:
if (tmpl_written and
((len(ptype) == 3 and (tmpl_val, tmpl_ptype) == (value, ptype_name)) or
(len(ptype) > 3 and (tuple(tmpl_val), tmpl_ptype) == (value, ptype_name)))):
return # Already in template and same value.
- _elem_props_set(elem, ptype, name, value, _elem_props_flags(tmpl_animatable, False))
+ _elem_props_set(elem, ptype, name, value, _elem_props_flags(tmpl_animatable, animated, False))
template[name][3] = True
else:
- _elem_props_set(elem, ptype, name, value, _elem_props_flags(animatable, False))
+ _elem_props_set(elem, ptype, name, value, _elem_props_flags(animatable, animated, False))
def elem_props_template_finalize(template, elem):
@@ -639,7 +648,7 @@ def elem_props_template_finalize(template, elem):
if written:
continue
ptype = FBX_PROPERTIES_DEFINITIONS[ptype_name]
- _elem_props_set(elem, ptype, name, value, _elem_props_flags(animatable, False))
+ _elem_props_set(elem, ptype, name, value, _elem_props_flags(animatable, False, False))
# ##### Templates #####
@@ -1196,7 +1205,7 @@ FBXExportSettings = namedtuple("FBXExportSettings", (
# * animations.
FBXExportData = namedtuple("FBXExportData", (
"templates", "templates_users", "connections",
- "settings", "scene", "objects", "animations", "frame_start", "frame_end",
+ "settings", "scene", "objects", "animations", "animated", "frame_start", "frame_end",
"data_empties", "data_lamps", "data_cameras", "data_meshes", "mesh_mat_indices",
"data_bones", "data_leaf_bones", "data_deformers_skin", "data_deformers_shape",
"data_world", "data_materials", "data_textures", "data_videos",