[Bf-extensions-cvs] [651596b] fbx_io_development: FBX import: First step toward animation (read anim fbxdata and parse its relations).
Bastien Montagne
noreply at git.blender.org
Fri May 23 17:49:38 CEST 2014
Commit: 651596bf4396923ec7eaaea02de6b64311764108
Author: Bastien Montagne
Date: Sun May 18 17:35:54 2014 +0200
https://developer.blender.org/rBA651596bf4396923ec7eaaea02de6b64311764108
FBX import: First step toward animation (read anim fbxdata and parse its relations).
Nothing usable yet!
===================================================================
M io_scene_fbx/import_fbx.py
===================================================================
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 724ad96..850b224 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -257,6 +257,21 @@ def elem_props_get_enum(elem, elem_prop_id, default=None):
return default
+"""
+def elem_props_get_compound(elem, elem_prop_id, default=None, getter=elem_props_find_first):
+ elem_prop = getter(elem, elem_prop_id)
+ if elem_prop is not None:
+ assert(elem_prop.props[0] == elem_prop_id)
+ assert(elem_prop.props[1] == b'Compound')
+ assert(elem_prop.props[2] == b'')
+ assert(elem_prop.props[3] == b'')
+
+ root = elem_prop_id + b'|'
+ def getter(elem, elem_prop_id):
+ return elem_props_find_first(elem, root + elem_prop_id)
+ return getter
+ return default
+"""
# ----------------------------------------------------------------------------
# Blender
@@ -390,7 +405,6 @@ def blen_read_armatures_add_bone(bl_obj, bl_arm, bones, b_uuid, matrices):
# We assume matrices in cluster are rest pose of bones (they are in Global space!).
# TransformLink is matrix of bone, in global space.
# TransformAssociateModel is matrix of armature, in global space (at bind time).
- # We seek for matrix of bone in armature space...
elm = elem_find_first(fbx_cdata, b'Transform', default=None)
mmat_bone = array_to_matrix4(elm.props[0]) if elm is not None else None
elm = elem_find_first(fbx_cdata, b'TransformLink', default=None)
@@ -400,6 +414,7 @@ def blen_read_armatures_add_bone(bl_obj, bl_arm, bones, b_uuid, matrices):
# ----
# Now, create the (edit)bone.
+ # We seek for matrix of bone in armature space...
bmat_arm = amat_glob.inverted() * bmat_glob
bone_name = elem_name_ensure_class(fbx_bdata, b'Model')
@@ -1409,7 +1424,7 @@ def load(operator, context, filepath="",
# armatures and bones, handled separately.
continue
fbx_obj, blen_data = fbx_item
- if fbx_obj.id != b'Model' or fbx_obj[2] == b'LimbNode':
+ if fbx_obj.id != b'Model' or fbx_obj.props[2] == b'LimbNode':
continue
# Create empty object or search for object data
@@ -1453,6 +1468,90 @@ def load(operator, context, filepath="",
blen_read_armatures(fbx_tmpl, armatures, scene, global_matrix)
_(); del _
+ # Animation!
+ def _():
+ stacks = {}
+ animlayers_ignored = set()
+
+ # AnimationStacks.
+ for fbx_uuid, fbx_item in fbx_table_nodes.items():
+ fbx_asdata, blen_data = fbx_item
+ if fbx_asdata.id != b'AnimationStack' or fbx_asdata.props[2] != b'':
+ continue
+ stacks[fbx_uuid] = (fbx_asdata, set(), {})
+
+ # AnimationLayers (only one per stack currently).
+ def get_astacks_from_alayer(al_uuid):
+ for as_uuid, as_ctype in fbx_connection_map.get(al_uuid, ()):
+ if as_ctype.props[0] != b'OO':
+ continue
+ fbx_asdata, _bl_asdata = fbx_table_nodes.get(as_uuid, (None, None))
+ if (fbx_asdata is None or fbx_asdata.id != b'AnimationStack' or fbx_asdata.props[2] != b'' or
+ as_uuid not in stacks or (as_uuid, al_uuid) in animlayers_ignored):
+ continue
+ yield as_uuid
+ for fbx_uuid, fbx_item in fbx_table_nodes.items():
+ fbx_aldata, _blen_data = fbx_item
+ if fbx_aldata.id != b'AnimationLayer' or fbx_aldata.props[2] != b'':
+ continue
+ for as_uuid in get_astacks_from_alayer(fbx_uuid):
+ _fbx_asdata, alayers, _acnodes = stacks[as_uuid]
+ alayers.add(fbx_uuid)
+ if len(alayers) > 1:
+ # For now, we only support one animlayer per animstack!
+ animlayers_ignored.add((as_uuid, fbx_uuid))
+
+ # AnimationCurveNodes (also the ones linked to actual animated data!).
+ curvenodes = {}
+ for fbx_uuid, fbx_item in fbx_table_nodes.items():
+ fbx_acndata, _blen_data = fbx_item
+ if fbx_acndata.id != b'AnimationCurveNode' or fbx_acndata.props[2] != b'':
+ continue
+ cnode = curvenodes[fbx_uuid] = {}
+ objs = []
+ for ob_uuid, ob_ctype in fbx_connection_map.get(fbx_uuid, ()):
+ if ob_ctype.props[0] != b'OP':
+ continue
+ lnk_prop = {
+ b'Lcl Location': "location",
+ b'Lcl Rotation': "rotation_euler",
+ b'Lcl Scaling': "scale"
+ }.get(ob_ctype.props[3], None)
+ if lnk_prop is None:
+ continue
+ objs.append((ob_uuid, lnk_prop))
+ for al_uuid, al_ctype in fbx_connection_map.get(acn_uuid, ()):
+ if al_ctype.props[0] != b'OO':
+ continue
+ fbx_aldata, _bl_aldata = fbx_table_nodes.get(al_uuid, (None, None))
+ if fbx_aldata is None or fbx_aldata.id != b'AnimationLayer' or fbx_aldata.props[2] != b'':
+ continue
+ for as_uuid in get_astacks_from_alayer(al_uuid):
+ _fbx_asdata, _alayers, objects = stacks[as_uuid]
+ for ob_uuid, ob_prop in objs:
+ objects.setdefault(ob_uuid, {})[fbx_uuid] = (cnode, ob_prop)
+
+ # AnimationCurves (real animation data).
+ for fbx_uuid, fbx_item in fbx_table_nodes.items():
+ fbx_acdata, _blen_data = fbx_item
+ if fbx_acdata.id != b'AnimationCurve' or fbx_acdata.props[2] != b'':
+ continue
+ for acn_uuid, acn_ctype in fbx_connection_map.get(ac_uuid, ()):
+ if acn_ctype.props[0] != b'OP':
+ continue
+ fbx_acndata, _bl_acndata = fbx_table_nodes.get(acn_uuid, (None, None))
+ if (fbx_acndata is None or fbx_acndata.id != b'AnimationCurveNode' or
+ fbx_acndata.props[2] != b'' or acn_uuid not in curvenodes):
+ continue
+ # Note this is an infamous simplification of the compound props stuff,
+ # seems to be standard naming but we'll probably have to be smarter to handle more exotic files?
+ channel = {b'd|X': 'x', b'd|Y': 'y', b'd|Z': 'z'}.get(acn_ctype.props[3], None)
+ curvenodes[acn_uuid][channel] = fbx_acdata
+
+ print(stacks)
+
+ _(); del _
+
def _():
# Parent objects, after we created them...
for fbx_uuid, fbx_item in fbx_table_nodes.items():
More information about the Bf-extensions-cvs
mailing list