Newer
Older
# Our matrix is in local space, time to bring it in its final desired space.
if parent:
if is_global:
# Move matrix to global Blender space.
matrix = (parent.matrix_rest_global if rest else parent.matrix_global) * matrix
elif parent.use_bake_space_transform(scene_data):
# Blender's and FBX's local space of parent may differ if we use bake_space_transform...
# Apply parent's *Blender* local space...
matrix = (parent.matrix_rest_local if rest else parent.matrix_local) * matrix
# ...and move it back into parent's *FBX* local space.
par_mat = parent.fbx_object_matrix(scene_data, rest=rest, local_space=True)
matrix = par_mat.inverted_safe() * matrix
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
if self.use_bake_space_transform(scene_data):
# If we bake the transforms we need to post-multiply inverse global transform.
# This means that the global transform will not apply to children of this transform.
matrix = matrix * scene_data.settings.global_matrix_inv
if is_global:
# In any case, pre-multiply the global matrix to get it in FBX global space!
matrix = scene_data.settings.global_matrix * matrix
return matrix
def fbx_object_tx(self, scene_data, rest=False, rot_euler_compat=None):
"""
Generate object transform data (always in local space when possible).
"""
matrix = self.fbx_object_matrix(scene_data, rest=rest)
loc, rot, scale = matrix.decompose()
matrix_rot = rot.to_matrix()
# quat -> euler, we always use 'XYZ' order, use ref rotation if given.
if rot_euler_compat is not None:
rot = rot.to_euler('XYZ', rot_euler_compat)
else:
rot = rot.to_euler('XYZ')
return loc, rot, scale, matrix, matrix_rot
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
def get_is_object(self):
return self._tag == 'OB'
is_object = property(get_is_object)
def get_is_dupli(self):
return self._tag == 'DP'
is_dupli = property(get_is_dupli)
def get_is_bone(self):
return self._tag == 'BO'
is_bone = property(get_is_bone)
def get_type(self):
if self._tag in {'OB', 'DP'}:
return self.bdata.type
return ...
type = property(get_type)
def get_armature(self):
if self._tag == 'BO':
return ObjectWrapper(self._ref)
return None
armature = property(get_armature)
def get_bones(self):
if self._tag == 'OB' and self.bdata.type == 'ARMATURE':
return (ObjectWrapper(bo, self.bdata) for bo in self.bdata.data.bones)
return ()
bones = property(get_bones)
def get_material_slots(self):
if self._tag in {'OB', 'DP'}:
return self.bdata.material_slots
return ()
material_slots = property(get_material_slots)
Bastien Montagne
committed
def is_deformed_by_armature(self, arm_obj):
if not (self.is_object and self.type == 'MESH'):
return False
Bastien Montagne
committed
if self.parent == arm_obj and self.bdata.parent_type == 'ARMATURE':
Bastien Montagne
committed
return True
for mod in self.bdata.modifiers:
if mod.type == 'ARMATURE' and mod.object == arm_obj.bdata:
return True
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
def dupli_list_create(self, scene, settings='PREVIEW'):
if self._tag == 'OB':
# Sigh, why raise exception here? :/
try:
self.bdata.dupli_list_create(scene, settings)
except:
pass
def dupli_list_clear(self):
if self._tag == 'OB':
self.bdata.dupli_list_clear()
def get_dupli_list(self):
if self._tag == 'OB':
return (ObjectWrapper(dup) for dup in self.bdata.dupli_list)
return ()
dupli_list = property(get_dupli_list)
def fbx_name_class(name, cls):
return FBX_NAME_CLASS_SEP.join((name, cls))
# ##### Top-level FBX data container. #####
# Helper sub-container gathering all exporter settings related to media (texture files).
Jens Ch. Restemeier
committed
FBXExportSettingsMedia = namedtuple("FBXExportSettingsMedia", (
"path_mode", "base_src", "base_dst", "subdir",
"embed_textures", "copy_set",
))
# Helper container gathering all exporter settings.
Jens Ch. Restemeier
committed
FBXExportSettings = namedtuple("FBXExportSettings", (
"report", "to_axes", "global_matrix", "global_scale",
"bake_space_transform", "global_matrix_inv", "global_matrix_inv_transposed",
"context_objects", "object_types", "use_mesh_modifiers",
Bastien Montagne
committed
"mesh_smooth_type", "use_mesh_edges", "use_tspace",
"use_armature_deform_only", "add_leaf_bones", "bone_correction_matrix", "bone_correction_matrix_inv",
"bake_anim", "bake_anim_use_nla_strips", "bake_anim_use_all_actions", "bake_anim_step", "bake_anim_simplify_factor",
"use_metadata", "media_settings", "use_custom_props",
))
# Helper container gathering some data we need multiple times:
# * templates.
# * settings, scene.
# * objects.
# * object data.
# * skinning data (binding armature/mesh).
# * animations.
Jens Ch. Restemeier
committed
FBXExportData = namedtuple("FBXExportData", (
"templates", "templates_users", "connections",
"settings", "scene", "objects", "animations", "frame_start", "frame_end",
"data_empties", "data_lamps", "data_cameras", "data_meshes", "mesh_mat_indices",
Bastien Montagne
committed
"data_bones", "data_leaf_bones", "data_deformers_skin", "data_deformers_shape",
"data_world", "data_materials", "data_textures", "data_videos",
))
Jens Ch. Restemeier
committed
# Helper container gathering all importer settings.
FBXImportSettings = namedtuple("FBXImportSettings", (
"report", "to_axes", "global_matrix", "global_scale",
Bastien Montagne
committed
"bake_space_transform", "global_matrix_inv", "global_matrix_inv_transposed",
Jens Ch. Restemeier
committed
"use_cycles", "use_image_search",
"use_alpha_decals", "decal_offset",
"use_custom_props", "use_custom_props_enum_as_string",
Bastien Montagne
committed
"cycles_material_wrap_map", "image_cache",
Bastien Montagne
committed
"ignore_leaf_bones", "automatic_bone_orientation", "bone_correction_matrix", "use_prepost_rot",