diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 6b6ceeb61a441b77866aff5f8219d14cfdad15e5..0347471d5092013e51d3cbcb1f527bfcc2fdf002 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -258,6 +258,11 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
         description="Export baked keyframe animation",
         default=True,
     )
+    bake_anim_use_nla_strips = BoolProperty(
+        name="NLA Strips",
+        description="Export each non-muted NLA strip as a separated FBX's AnimStack, if any",
+        default=True,
+    )
     bake_anim_step = FloatProperty(
         name="Sampling Rate",
         description=("How often to evaluate animated values (in frames)"),
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 2133cb5f07922099945157a6f466d4c4f7f86bd1..f26dfc02f2b369f472b53e92b6011e2f0efc2826 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -254,14 +254,20 @@ def get_blender_bone_cluster_key(armature, mesh, bone):
                      get_blenderID_key(bone), "SubDeformerCluster"))
 
 
-def get_blender_anim_stack_key(scene):
+def get_blender_anim_stack_key(scene, ID=None):
     """Return single anim stack key."""
-    return "|".join((get_blenderID_key(scene), "AnimStack"))
+    if ID:
+        return "|".join((get_blenderID_key(scene), get_blenderID_key(ID), "AnimStack"))
+    else:
+        return "|".join((get_blenderID_key(scene), "AnimStack"))
 
 
-def get_blender_anim_layer_key(ID):
+def get_blender_anim_layer_key(scene, ID=None):
     """Return ID's anim layer key."""
-    return "|".join((get_blenderID_key(ID), "AnimLayer"))
+    if ID:
+        return "|".join((get_blenderID_key(scene), get_blenderID_key(ID), "AnimLayer"))
+    else:
+        return "|".join((get_blenderID_key(scene), "AnimLayer"))
 
 
 def get_blender_anim_curve_node_key(ID, fbx_prop_name):
@@ -1917,77 +1923,76 @@ def fbx_data_animation_elements(root, scene_data):
     def keys_to_ktimes(keys):
         return (int(v) for v in units_convert_iter((f / fps for f, _v in keys), "second", "ktime"))
 
-    astack_key, alayers, alayer_key = animations
-
-    # Animation stack.
-    astack = elem_data_single_int64(root, b"AnimationStack", get_fbxuid_from_key(astack_key))
-    astack.add_string(fbx_name_class(scene.name.encode(), b"AnimStack"))
-    astack.add_string(b"")
+    # Animation stacks.
+    for astack_key, alayers, alayer_key, name, f_start, f_end in animations:
+        astack = elem_data_single_int64(root, b"AnimationStack", get_fbxuid_from_key(astack_key))
+        astack.add_string(fbx_name_class(name, b"AnimStack"))
+        astack.add_string(b"")
+
+        astack_tmpl = elem_props_template_init(scene_data.templates, b"AnimationStack")
+        astack_props = elem_properties(astack)
+        r = scene_data.scene.render
+        fps = r.fps / r.fps_base
+        start = int(units_convert(f_start / fps, "second", "ktime"))
+        end = int(units_convert(f_end / fps, "second", "ktime"))
+        elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStart", start)
+        elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStop", end)
+        elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStart", start)
+        elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStop", end)
+        elem_props_template_finalize(astack_tmpl, astack_props)
+
+        # For now, only one layer for all animations.
+        alayer = elem_data_single_int64(root, b"AnimationLayer", get_fbxuid_from_key(alayer_key))
+        alayer.add_string(fbx_name_class(name, b"AnimLayer"))
+        alayer.add_string(b"")
+
+        for obj, (alayer_key, acurvenodes) in alayers.items():
+            # Animation layer.
+            # alayer = elem_data_single_int64(root, b"AnimationLayer", get_fbxuid_from_key(alayer_key))
+            # alayer.add_string(fbx_name_class(obj.name.encode(), b"AnimLayer"))
+            # alayer.add_string(b"")
 
-    astack_tmpl = elem_props_template_init(scene_data.templates, b"AnimationStack")
-    astack_props = elem_properties(astack)
-    r = scene_data.scene.render
-    fps = r.fps / r.fps_base
-    f_start = int(units_convert(scene_data.scene.frame_start / fps, "second", "ktime"))
-    f_end = int(units_convert(scene_data.scene.frame_end / fps, "second", "ktime"))
-    elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStart", f_start)
-    elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStop", f_end)
-    elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStart", f_start)
-    elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStop", f_end)
-    elem_props_template_finalize(astack_tmpl, astack_props)
-
-    # For now, only one layer for all animations.
-    alayer = elem_data_single_int64(root, b"AnimationLayer", get_fbxuid_from_key(alayer_key))
-    alayer.add_string(fbx_name_class(scene.name.encode(), b"AnimLayer"))
-    alayer.add_string(b"")
-
-    for obj, (alayer_key, acurvenodes) in alayers.items():
-        # Animation layer.
-        # alayer = elem_data_single_int64(root, b"AnimationLayer", get_fbxuid_from_key(alayer_key))
-        # alayer.add_string(fbx_name_class(obj.name.encode(), b"AnimLayer"))
-        # alayer.add_string(b"")
-
-        for fbx_prop, (acurvenode_key, acurves, acurvenode_name) in acurvenodes.items():
-            # Animation curve node.
-            acurvenode = elem_data_single_int64(root, b"AnimationCurveNode", get_fbxuid_from_key(acurvenode_key))
-            acurvenode.add_string(fbx_name_class(acurvenode_name.encode(), b"AnimCurveNode"))
-            acurvenode.add_string(b"")
-
-            acn_tmpl = elem_props_template_init(scene_data.templates, b"AnimationCurveNode")
-            acn_props = elem_properties(acurvenode)
-
-            for fbx_item, (acurve_key, def_value, keys, _acurve_valid) in acurves.items():
-                elem_props_template_set(acn_tmpl, acn_props, "p_number", fbx_item.encode(), def_value, animatable=True)
-
-                # Only create Animation curve if needed!
-                if keys:
-                    acurve = elem_data_single_int64(root, b"AnimationCurve", get_fbxuid_from_key(acurve_key))
-                    acurve.add_string(fbx_name_class(b"", b"AnimCurve"))
-                    acurve.add_string(b"")
-
-                    # key attributes...
-                    nbr_keys = len(keys)
-                    # flags...
-                    keyattr_flags = (
-                        1 << 3 |   # interpolation mode, 1 = constant, 2 = linear, 3 = cubic.
-                        1 << 8 |   # tangent mode, 8 = auto, 9 = TCB, 10 = user, 11 = generic break,
-                        1 << 13 |  # tangent mode, 12 = generic clamp, 13 = generic time independent,
-                        1 << 14 |  # tangent mode, 13 + 14 = generic clamp progressive.
-                        0,
-                    )
-                    # Maybe values controlling TCB & co???
-                    keyattr_datafloat = (0.0, 0.0, 9.419963346924634e-30, 0.0)
-
-                    # And now, the *real* data!
-                    elem_data_single_float64(acurve, b"Default", def_value)
-                    elem_data_single_int32(acurve, b"KeyVer", FBX_ANIM_KEY_VERSION)
-                    elem_data_single_int64_array(acurve, b"KeyTime", keys_to_ktimes(keys))
-                    elem_data_single_float32_array(acurve, b"KeyValueFloat", (v for _f, v in keys))
-                    elem_data_single_int32_array(acurve, b"KeyAttrFlags", keyattr_flags)
-                    elem_data_single_float32_array(acurve, b"KeyAttrDataFloat", keyattr_datafloat)
-                    elem_data_single_int32_array(acurve, b"KeyAttrRefCount", (nbr_keys,))
-
-            elem_props_template_finalize(acn_tmpl, acn_props)
+            for fbx_prop, (acurvenode_key, acurves, acurvenode_name) in acurvenodes.items():
+                # Animation curve node.
+                acurvenode = elem_data_single_int64(root, b"AnimationCurveNode", get_fbxuid_from_key(acurvenode_key))
+                acurvenode.add_string(fbx_name_class(acurvenode_name.encode(), b"AnimCurveNode"))
+                acurvenode.add_string(b"")
+
+                acn_tmpl = elem_props_template_init(scene_data.templates, b"AnimationCurveNode")
+                acn_props = elem_properties(acurvenode)
+
+                for fbx_item, (acurve_key, def_value, keys, _acurve_valid) in acurves.items():
+                    elem_props_template_set(acn_tmpl, acn_props, "p_number", fbx_item.encode(), def_value, animatable=True)
+
+                    # Only create Animation curve if needed!
+                    if keys:
+                        acurve = elem_data_single_int64(root, b"AnimationCurve", get_fbxuid_from_key(acurve_key))
+                        acurve.add_string(fbx_name_class(b"", b"AnimCurve"))
+                        acurve.add_string(b"")
+
+                        # key attributes...
+                        nbr_keys = len(keys)
+                        # flags...
+                        keyattr_flags = (
+                            1 << 3 |   # interpolation mode, 1 = constant, 2 = linear, 3 = cubic.
+                            1 << 8 |   # tangent mode, 8 = auto, 9 = TCB, 10 = user, 11 = generic break,
+                            1 << 13 |  # tangent mode, 12 = generic clamp, 13 = generic time independent,
+                            1 << 14 |  # tangent mode, 13 + 14 = generic clamp progressive.
+                            0,
+                        )
+                        # Maybe values controlling TCB & co???
+                        keyattr_datafloat = (0.0, 0.0, 9.419963346924634e-30, 0.0)
+
+                        # And now, the *real* data!
+                        elem_data_single_float64(acurve, b"Default", def_value)
+                        elem_data_single_int32(acurve, b"KeyVer", FBX_ANIM_KEY_VERSION)
+                        elem_data_single_int64_array(acurve, b"KeyTime", keys_to_ktimes(keys))
+                        elem_data_single_float32_array(acurve, b"KeyValueFloat", (v for _f, v in keys))
+                        elem_data_single_int32_array(acurve, b"KeyAttrFlags", keyattr_flags)
+                        elem_data_single_float32_array(acurve, b"KeyAttrDataFloat", keyattr_datafloat)
+                        elem_data_single_int32_array(acurve, b"KeyAttrRefCount", (nbr_keys,))
+
+                elem_props_template_finalize(acn_tmpl, acn_props)
 
 
 ##### Top-level FBX data container. #####
@@ -2143,9 +2148,9 @@ def fbx_animations_simplify(scene_data, animdata):
         p_key_write[:] = [True] * len(p_key_write)
 
 
-def fbx_animations_objects(scene_data):
+def fbx_animations_objects_do(scene_data, ref_id, f_start, f_end):
     """
-    Generate animation data from objects.
+    Generate animation data (a single AnimStack) from objects, for a given frame range.
     """
     objects = scene_data.objects
     bake_step = scene_data.settings.bake_anim_step
@@ -2164,8 +2169,8 @@ def fbx_animations_objects(scene_data):
 
     p_rots = {}
 
-    currframe = scene.frame_start
-    while currframe < scene.frame_end:
+    currframe = f_start
+    while currframe < f_end:
         scene.frame_set(int(currframe), currframe - int(currframe))
         for obj in objects.keys():
             # Get PoseBone from bone...
@@ -2217,9 +2222,54 @@ def fbx_animations_objects(scene_data):
             del final_keys[grp]
 
         if final_keys:
-            animations[obj] = (get_blender_anim_layer_key(obj), final_keys)
+            animations[obj] = (get_blender_anim_layer_key(scene, obj), final_keys)
+
+    astack_key = get_blender_anim_stack_key(scene, ref_id)
+    alayer_key = get_blender_anim_layer_key(scene, ref_id)
+    name = (ref_id.name if ref_id else scene.name).encode()
+
+    return (astack_key, animations, alayer_key, name, f_start, f_end) if animations else None
+
+
+def fbx_animations_objects(scene_data):
+    """
+    Generate global animation data from objects.
+    """
+    scene = scene_data.scene
+    animations = []
+
+    # Global (containing everything) animstack.
+    anim = fbx_animations_objects_do(scene_data, None, scene.frame_start, scene.frame_end)
+    if anim is not None:
+        animations.append(anim)
+
+    # Per-NLA strip animstacks.
+    if scene_data.settings.bake_anim_use_nla_strips:
+        strips = []
+        for obj in scene_data.objects:
+            # NLA tracks only for objects, not bones!
+            if not isinstance(obj, Object) or not obj.animation_data:
+                continue
+            for track in obj.animation_data.nla_tracks:
+                if track.mute:
+                    continue
+                for strip in track.strips:
+                    if strip.mute:
+                        continue
+                    strips.append(strip)
+                    strip.mute = True
+
+        for strip in strips:
+            strip.mute = False
+            anim = fbx_animations_objects_do(scene_data, strip, strip.frame_start, strip.frame_end)
+            if anim is not None:
+                animations.append(anim)
+            strip.mute = True
+
+        for strip in strips:
+            strip.mute = False
 
-    return (get_blender_anim_stack_key(scene), animations, get_blender_anim_layer_key(scene)) if animations else None
+    return animations
 
 
 def fbx_data_from_scene(scene, settings):
@@ -2373,19 +2423,23 @@ def fbx_data_from_scene(scene, settings):
         templates[b"Video"] = fbx_template_def_video(scene, settings, nbr_users=len(data_videos))
 
     if animations:
-        # One stack!
-        templates[b"AnimationStack"] = fbx_template_def_animstack(scene, settings, nbr_users=1)
+        nbr_astacks = len(animations)
+        nbr_acnodes = 0
+        nbr_acurves = 0
+        for _astack_key, astack, _al, _n, _fs, _fe in animations:
+            for _alayer_key, alayer in astack.values():
+                for _acnode_key, acnode, _acnode_name in alayer.values():
+                    nbr_acnodes += 1
+                    for _acurve_key, _dval, acurve, acurve_valid in acnode.values():
+                        if acurve:
+                            nbr_acurves += 1
+
+        templates[b"AnimationStack"] = fbx_template_def_animstack(scene, settings, nbr_users=nbr_astacks)
         # Would be nice to have one layer per animated object, but this seems tricky and not that well supported.
-        # So for now, only one layer for all animations.
-        templates[b"AnimationLayer"] = fbx_template_def_animlayer(scene, settings, nbr_users=1)
-        # As much curve node as animated properties.
-        nbr = sum(len(al) for _kal, al in animations[1].values())
-        templates[b"AnimationCurveNode"] = fbx_template_def_animcurvenode(scene, settings, nbr_users=nbr)
-        # And the number of curves themselves...
-        nbr = sum(1 if ac else 0 for _kal, al in animations[1].values()
-                                 for _kacn, acn, _acn_n in al.values()
-                                 for _kac, _dv, ac, _acv in acn.values())
-        templates[b"AnimationCurve"] = fbx_template_def_animcurve(scene, settings, nbr_users=nbr)
+        # So for now, only one layer per anim stack.
+        templates[b"AnimationLayer"] = fbx_template_def_animlayer(scene, settings, nbr_users=nbr_astacks)
+        templates[b"AnimationCurveNode"] = fbx_template_def_animcurvenode(scene, settings, nbr_users=nbr_acnodes)
+        templates[b"AnimationCurve"] = fbx_template_def_animcurve(scene, settings, nbr_users=nbr_acurves)
 
     templates_users = sum(tmpl.nbr_users for tmpl in templates.values())
 
@@ -2484,13 +2538,13 @@ def fbx_data_from_scene(scene, settings):
             connections.append((b"OO", get_fbxuid_from_key(vid_key), get_fbxuid_from_key(tex_key), None))
 
     #Animations
-    if animations:
+    for astack_key, astack, alayer_key, _name, _fstart, _fend in animations:
         # Animstack itself is linked nowhere!
-        astack_id = get_fbxuid_from_key(animations[0])
+        astack_id = get_fbxuid_from_key(astack_key)
         # For now, only one layer!
-        alayer_id = get_fbxuid_from_key(animations[2])
+        alayer_id = get_fbxuid_from_key(alayer_key)
         connections.append((b"OO", alayer_id, astack_id, None))
-        for obj, (alayer_key, acurvenodes) in animations[1].items():
+        for obj, (alayer_key, acurvenodes) in astack.items():
             obj_id = get_fbxuid_from_key(objects[obj])
             # Animlayer -> animstack.
             # alayer_id = get_fbxuid_from_key(alayer_key)
@@ -2723,14 +2777,14 @@ def fbx_connections_elements(root, scene_data):
 
 def fbx_takes_elements(root, scene_data):
     """
-    Animations. Have yet to check how this work...
+    Animations.
     """
     # XXX Are takes needed at all in new anim system?
     takes = elem_empty(root, b"Takes")
     elem_data_single_string(takes, b"Current", b"")
 
     animations = scene_data.animations
-    if animations is None:
+    if not animations:
         return
     scene = scene_data.scene
     take_name = scene.name.encode()
@@ -2756,7 +2810,7 @@ FBXSettings = namedtuple("FBXSettings", (
     "bake_space_transform", "global_matrix_inv", "global_matrix_inv_transposed",
     "context_objects", "object_types", "use_mesh_modifiers",
     "mesh_smooth_type", "use_mesh_edges", "use_tspace", "use_armature_deform_only",
-    "bake_anim", "bake_anim_step", "bake_anim_simplify_factor",
+    "bake_anim", "bake_anim_use_nla_strips", "bake_anim_step", "bake_anim_simplify_factor",
     "use_metadata", "media_settings", "use_custom_properties",
 ))
 
@@ -2771,6 +2825,7 @@ def save_single(operator, scene, filepath="",
                 use_mesh_modifiers=True,
                 mesh_smooth_type='FACE',
                 bake_anim=True,
+                bake_anim_use_nla_strips=True,
                 bake_anim_step=1.0,
                 bake_anim_simplify_factor=1.0,
                 use_metadata=True,
@@ -2810,7 +2865,7 @@ def save_single(operator, scene, filepath="",
         bake_space_transform, global_matrix_inv, global_matrix_inv_transposed,
         context_objects, object_types, use_mesh_modifiers,
         mesh_smooth_type, use_mesh_edges, use_tspace, False,
-        bake_anim, bake_anim_step, bake_anim_simplify_factor,
+        bake_anim, bake_anim_use_nla_strips, bake_anim_step, bake_anim_simplify_factor,
         False, media_settings, use_custom_properties,
     )