Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
fw('\n\t\t\tProperty: "DecayType", "enum", "",0')
fw('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.distance)
fw('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0'
'\n\t\t\tProperty: "NearAttenuationStart", "double", "",0'
'\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0'
'\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0'
'\n\t\t\tProperty: "FarAttenuationStart", "double", "",0'
'\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0'
)
fw('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow)
fw('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1')
fw('\n\t\t}')
fw('\n\t\tMultiLayer: 0'
'\n\t\tMultiTake: 0'
'\n\t\tShading: Y'
'\n\t\tCulling: "CullingOff"'
'\n\t\tTypeFlags: "Light"'
'\n\t\tGeometryVersion: 124'
'\n\t}'
)
# matrixOnly is not used at the moment
def write_null(my_null=None, fbxName=None, fbxType="Null", fbxTypeFlags="Null"):
# ob can be null
if not fbxName:
fbxName = my_null.fbxName
fw('\n\tModel: "Model::%s", "%s" {' % (fbxName, fbxType))
fw('\n\t\tVersion: 232')
if my_null:
poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3]
else:
poseMatrix = write_object_props()[3]
pose_items.append((fbxName, poseMatrix))
fw('\n\t\t}'
'\n\t\tMultiLayer: 0'
'\n\t\tMultiTake: 1'
'\n\t\tShading: Y'
'\n\t\tCulling: "CullingOff"'
)
fw('\n\t\tTypeFlags: "%s"' % fbxTypeFlags)
fw('\n\t}')
# Material Settings
if world:
world_amb = world.ambient_color[:]
else:
world_amb = 0.0, 0.0, 0.0 # default value
def write_material(matname, mat):
# Todo, add more material Properties.
if mat:
mat_cold = tuple(mat.diffuse_color)
mat_cols = tuple(mat.specular_color)
#mat_colm = tuple(mat.mirCol) # we wont use the mirror color
mat_colamb = world_amb
mat_dif = mat.diffuse_intensity
mat_amb = mat.ambient
mat_hard = (float(mat.specular_hardness) - 1.0) / 5.10
mat_spec = mat.specular_intensity / 2.0
mat_alpha = mat.alpha
mat_emit = mat.emit
mat_shadeless = mat.use_shadeless
if mat_shadeless:
mat_shader = 'Lambert'
else:
if mat.diffuse_shader == 'LAMBERT':
mat_shader = 'Lambert'
else:
mat_shader = 'Phong'
else:
mat_cols = mat_cold = 0.8, 0.8, 0.8
mat_colamb = 0.0, 0.0, 0.0
# mat_colm
mat_dif = 1.0
mat_amb = 0.5
mat_hard = 20.0
mat_spec = 0.2
mat_alpha = 1.0
mat_emit = 0.0
mat_shadeless = False
mat_shader = 'Phong'
fw('\n\t\tVersion: 102')
fw('\n\t\tShadingModel: "%s"' % mat_shader.lower())
fw('\n\t\tMultiLayer: 0')
fw('\n\t\tProperties60: {')
fw('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader)
fw('\n\t\t\tProperty: "MultiLayer", "bool", "",0')
fw('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender
fw('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit)
fw('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb)
fw('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb)
fw('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold)
fw('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif)
fw('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0')
fw('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1')
fw('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha))
if not mat_shadeless:
fw('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols)
fw('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec)
fw('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0')
fw('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0')
fw('\n\t\t\tProperty: "ReflectionFactor", "double", "",1')
fw('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0')
fw('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb)
fw('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold)
if not mat_shadeless:
fw('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols)
fw('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard)
fw('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha)
if not mat_shadeless:
fw('\n\t\t\tProperty: "Reflectivity", "double", "",0')
# tex is an Image (Arystan)
def write_video(texname, tex):
# Same as texture really!
Campbell Barton
committed
Type: "Clip"
Properties60: {
Property: "FrameRate", "double", "",0
Property: "LastFrame", "int", "",0
Property: "Width", "int", "",0
Property: "Height", "int", "",0''')
if tex:
Campbell Barton
committed
fname_rel = bpy_extras.io_utils.path_reference(tex.filepath, base_src, base_dst, path_mode, "", copy_set)
fname_strip = bpy.path.basename(fname_rel)
else:
fname_strip = fname_rel = ""
fw('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip)
Campbell Barton
committed
Property: "StartFrame", "int", "",0
Property: "StopFrame", "int", "",0
Property: "PlaySpeed", "double", "",1
Property: "Offset", "KTime", "",0
Property: "InterlaceMode", "enum", "",0
Property: "FreeRunning", "bool", "",0
Property: "Loop", "bool", "",0
Property: "AccessMode", "enum", "",0
}
UseMipMap: 0''')
fw('\n\t\tFilename: "%s"' % fname_strip)
fw('\n\t\tRelativeFilename: "%s"' % fname_rel) # make relative
fw('\n\t}')
def write_texture(texname, tex, num):
# if tex is None then this is a dummy tex
fw('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname)
fw('\n\t\tType: "TextureVideoClip"')
fw('\n\t\tVersion: 202')
# TODO, rare case _empty_ exists as a name.
Campbell Barton
committed
Properties60: {
Property: "Translation", "Vector", "A+",0,0,0
Property: "Rotation", "Vector", "A+",0,0,0
Property: "Scaling", "Vector", "A+",1,1,1''')
fw('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num)
# WrapModeU/V 0==rep, 1==clamp, TODO add support
Campbell Barton
committed
Property: "TextureTypeUse", "enum", "",0
Property: "CurrentTextureBlendMode", "enum", "",1
Property: "UseMaterial", "bool", "",0
Property: "UseMipMap", "bool", "",0
Property: "CurrentMappingType", "enum", "",0
Property: "UVSwap", "bool", "",0''')
fw('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.use_clamp_x)
fw('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.use_clamp_y)
Campbell Barton
committed
Property: "TextureRotationPivot", "Vector3D", "",0,0,0
Property: "TextureScalingPivot", "Vector3D", "",0,0,0
Property: "VideoProperty", "object", ""
}''')
if tex:
Campbell Barton
committed
fname_rel = bpy_extras.io_utils.path_reference(tex.filepath, base_src, base_dst, path_mode, "", copy_set)
fname_strip = bpy.path.basename(bpy.path.abspath(fname_rel))
else:
fname_strip = fname_rel = ""
fw('\n\t\tFileName: "%s"' % fname_strip)
fw('\n\t\tRelativeFilename: "%s"' % fname_rel) # need some make relative command
Campbell Barton
committed
ModelUVTranslation: 0,0
ModelUVScaling: 1,1
Texture_Alpha_Source: "None"
Cropping: 0,0,0,0
}''')
def write_deformer_skin(obname):
'''
Each mesh has its own deformer
'''
fw('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname)
fw('''
Campbell Barton
committed
Version: 100
MultiLayer: 0
Type: "Skin"
Properties60: {
}
Link_DeformAcuracy: 50
}''')
# in the example was 'Bip01 L Thigh_2'
def write_sub_deformer_skin(my_mesh, my_bone, weights):
'''
Each subdeformer is spesific to a mesh, but the bone it links to can be used by many sub-deformers
So the SubDeformer needs the mesh-object name as a prefix to make it unique
Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer,
a but silly but dosnt really matter
'''
fw('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName))
Campbell Barton
committed
Version: 100
MultiLayer: 0
Type: "Cluster"
Properties60: {
Property: "SrcModel", "object", ""
Property: "SrcModelReference", "object", ""
}
UserData: "", ""''')
# Support for bone parents
if my_mesh.fbxBoneParent:
if my_mesh.fbxBoneParent == my_bone:
# TODO - this is a bit lazy, we could have a simple write loop
# for this case because all weights are 1.0 but for now this is ok
# Parent Bones arent used all that much anyway.
vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.vertices))]
else:
# This bone is not a parent of this mesh object, no weights
vgroup_data = []
else:
# Normal weight painted mesh
if my_bone.blenName in weights[0]:
Campbell Barton
committed
# Before we used normalized weight list
group_index = weights[0].index(my_bone.blenName)
vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]]
else:
vgroup_data = []
i = -1
for vg in vgroup_data:
if i == -1:
i = 0
else:
if i == 23:
i = 0
i += 1
i = -1
for vg in vgroup_data:
if i == -1:
i = 0
else:
if i == 38:
i = 0
i += 1
if my_mesh.fbxParent:
# TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible!
m = (my_mesh.matrixWorld.inverted() * my_bone.fbxArm.matrixWorld.copy() * my_bone.restMatrix) * mtx4_z90
else:
# Yes! this is it... - but dosnt work when the mesh is a.
m = (my_mesh.matrixWorld.inverted() * my_bone.fbxArm.matrixWorld.copy() * my_bone.restMatrix) * mtx4_z90
#m = mtx4_z90 * my_bone.restMatrix
matstr = mat4x4str(m)
matstr_i = mat4x4str(m.inverted())
fw('\n\t\tTransform: %s' % matstr_i) # THIS IS __NOT__ THE GLOBAL MATRIX AS DOCUMENTED :/
fw('\n\t\tTransformLink: %s' % matstr)
fw('\n\t}')
def write_mesh(my_mesh):
me = my_mesh.blenData
# if there are non NULL materials on this mesh
do_materials = bool(my_mesh.blenMaterials)
do_textures = bool(my_mesh.blenTextures)
do_uvs = bool(me.uv_textures)
do_shapekeys = bool(my_mesh.blenObject.data.shape_keys and len(my_mesh.blenObject.data.vertices) == len(me.vertices))
fw('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName)
fw('\n\t\tVersion: 232') # newline is added in write_object_props
# convert into lists once.
me_vertices = me.vertices[:]
me_edges = me.edges[:] if use_mesh_edges else ()
me_faces = me.faces[:]
poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3]
pose_items.append((my_mesh.fbxName, poseMatrix))
if do_shapekeys:
for kb in my_mesh.blenObject.data.shape_keys.key_blocks[1:]:
fw('\n\t\t\tProperty: "%s", "Number", "AN",0' % kb.name)
fw('\n\t\t}')
fw('\n\t\tMultiLayer: 0'
'\n\t\tMultiTake: 1'
'\n\t\tShading: Y'
'\n\t\tCulling: "CullingOff"'
)
# Write the Real Mesh data here
i = -1
for v in me_vertices:
if i == -1:
i = 0
else:
if i == 7:
i = 0
i += 1
i = -1
for f in me_faces:
fi = f.vertices[:]
# last index XORd w. -1 indicates end of face
if i == -1:
if len(fi) == 3:
else:
fw('%i,%i,%i,%i' % (fi[0], fi[1], fi[2], fi[3] ^ -1))
i = 0
else:
if i == 13:
i = 0
if len(fi) == 3:
else:
fw(',%i,%i,%i,%i' % (fi[0], fi[1], fi[2], fi[3] ^ -1))
i += 1
# write loose edges as faces.
for ed in me_edges:
if ed.is_loose:
ed_val = ed.vertices[:]
ed_val = ed_val[0], ed_val[-1] ^ -1
if i == -1:
i = 0
else:
if i == 13:
i = 0
i += 1
i = -1
for ed in me_edges:
if i == -1:
i = 0
else:
if i == 13:
i = 0
i += 1
Campbell Barton
committed
LayerElementNormal: 0 {
Version: 101
Name: ""
MappingInformationType: "ByVertice"
ReferenceInformationType: "Direct"
Normals: ''')
i = -1
for v in me_vertices:
if i == -1:
i = 0
else:
if i == 2:
i = 0
i += 1
# Write Face Smoothing
Campbell Barton
committed
if mesh_smooth_type == 'FACE':
Campbell Barton
committed
LayerElementSmoothing: 0 {
Version: 102
Name: ""
MappingInformationType: "ByPolygon"
ReferenceInformationType: "Direct"
Smoothing: ''')
Campbell Barton
committed
i = -1
for f in me_faces:
if i == -1:
i = 0
Campbell Barton
committed
else:
if i == 54:
Campbell Barton
committed
i = 0
Campbell Barton
committed
i += 1
Campbell Barton
committed
elif mesh_smooth_type == 'EDGE':
# Write Edge Smoothing
Campbell Barton
committed
LayerElementSmoothing: 0 {
Version: 101
Name: ""
MappingInformationType: "ByEdge"
ReferenceInformationType: "Direct"
Smoothing: ''')
Campbell Barton
committed
i = -1
for ed in me_edges:
if i == -1:
i = 0
Campbell Barton
committed
else:
if i == 54:
Campbell Barton
committed
i = 0
Campbell Barton
committed
i += 1
Campbell Barton
committed
elif mesh_smooth_type == 'OFF':
pass
else:
raise Exception("invalid mesh_smooth_type: %r" % mesh_smooth_type)
# Write VertexColor Layers
# note, no programs seem to use this info :/
collayers = []
if len(me.vertex_colors):
collayers = me.vertex_colors
for colindex, collayer in enumerate(collayers):
fw('\n\t\tLayerElementColor: %i {' % colindex)
fw('\n\t\t\tVersion: 101')
fw('\n\t\t\tName: "%s"' % collayer.name)
Campbell Barton
committed
MappingInformationType: "ByPolygonVertex"
ReferenceInformationType: "IndexToDirect"
Colors: ''')
i = -1
ii = 0 # Count how many Colors we write
for fi, cf in enumerate(collayer.data):
if len(me_faces[fi].vertices) == 4:
colors = cf.color1[:], cf.color2[:], cf.color3[:], cf.color4[:]
else:
colors = cf.color1[:], cf.color2[:], cf.color3[:]
for col in colors:
if i == -1:
i = 0
else:
if i == 7:
i = 0
i += 1
ii += 1 # One more Color
i = -1
for j in range(ii):
if i == -1:
i = 0
else:
if i == 55:
i = 0
i += 1
# Write UV and texture layers.
uvlayers = []
if do_uvs:
uvlayers = me.uv_textures
for uvindex, uvlayer in enumerate(me.uv_textures):
fw('\n\t\tLayerElementUV: %i {' % uvindex)
fw('\n\t\t\tVersion: 101')
fw('\n\t\t\tName: "%s"' % uvlayer.name)
Campbell Barton
committed
MappingInformationType: "ByPolygonVertex"
ReferenceInformationType: "IndexToDirect"
UV: ''')
i = -1
ii = 0 # Count how many UVs we write
for uf in uvlayer.data:
# workaround, since uf.uv iteration is wrong atm
for uv in uf.uv:
if i == -1:
i = 0
else:
if i == 7:
i = 0
i += 1
ii += 1 # One more UV
i = -1
for j in range(ii):
if i == -1:
i = 0
else:
if i == 55:
i = 0
i += 1
if do_textures:
fw('\n\t\tLayerElementTexture: %i {' % uvindex)
fw('\n\t\t\tVersion: 101')
fw('\n\t\t\tName: "%s"' % uvlayer.name)
if len(my_mesh.blenTextures) == 1:
else:
fw('\n\t\t\tReferenceInformationType: "IndexToDirect"')
fw('\n\t\t\tBlendMode: "Translucent"')
fw('\n\t\t\tTextureAlpha: 1')
fw('\n\t\t\tTextureId: ')
if len(my_mesh.blenTextures) == 1:
else:
texture_mapping_local = {None: -1}
i = 0 # 1 for dummy
for tex in my_mesh.blenTextures:
if tex: # None is set above
texture_mapping_local[tex] = i
i += 1
i = -1
for f in uvlayer.data:
img_key = f.image
if i == -1:
i = 0
else:
if i == 55:
i = 0
i += 1
else:
Campbell Barton
committed
LayerElementTexture: 0 {
Version: 101
Name: ""
MappingInformationType: "NoMappingInformation"
ReferenceInformationType: "IndexToDirect"
BlendMode: "Translucent"
TextureAlpha: 1
TextureId: ''')
# Done with UV/textures.
if do_materials:
fw('\n\t\tLayerElementMaterial: 0 {')
fw('\n\t\t\tVersion: 101')
fw('\n\t\t\tName: ""')
if len(my_mesh.blenMaterials) == 1:
else:
fw('\n\t\t\tReferenceInformationType: "IndexToDirect"')
fw('\n\t\t\tMaterials: ')
if len(my_mesh.blenMaterials) == 1:
else:
# Build a material mapping for this
material_mapping_local = {} # local-mat & tex : global index.
for j, mat_tex_pair in enumerate(my_mesh.blenMaterials):
material_mapping_local[mat_tex_pair] = j
mats = my_mesh.blenMaterialList
if me.uv_textures.active:
uv_faces = me.uv_textures.active.data
else:
uv_faces = [None] * len(me_faces)
i = -1
for f, uf in zip(me_faces, uv_faces):
try:
mat = mats[f.material_index]
except:
mat = None
if do_uvs:
tex = uf.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/
else:
tex = None
if i == -1:
i = 0
fw('%s' % material_mapping_local[mat, tex]) # None for mat or tex is ok
else:
if i == 55:
i = 0
i += 1
Campbell Barton
committed
Layer: 0 {
Version: 100
LayerElement: {
Type: "LayerElementNormal"
TypedIndex: 0
}''')
if do_materials:
Campbell Barton
committed
LayerElement: {
Type: "LayerElementMaterial"
TypedIndex: 0
}''')
Campbell Barton
committed
# Smoothing info
if mesh_smooth_type != 'OFF':
Campbell Barton
committed
LayerElement: {
Type: "LayerElementSmoothing"
TypedIndex: 0
}''')
Campbell Barton
committed
# Always write this
if do_textures:
Campbell Barton
committed
LayerElement: {
Type: "LayerElementTexture"
TypedIndex: 0
}''')
if me.vertex_colors:
Campbell Barton
committed
LayerElement: {
Type: "LayerElementColor"
TypedIndex: 0
}''')
if do_uvs: # same as me.faceUV
Campbell Barton
committed
LayerElement: {
Type: "LayerElementUV"
TypedIndex: 0
}''')
if len(uvlayers) > 1:
for i in range(1, len(uvlayers)):
fw('\n\t\tLayer: %i {' % i)
fw('\n\t\t\tVersion: 100')
Campbell Barton
committed
LayerElement: {
Type: "LayerElementUV"''')
fw('\n\t\t\t\tTypedIndex: %i' % i)
fw('\n\t\t\t}')
if do_textures:
Campbell Barton
committed
LayerElement: {
Type: "LayerElementTexture"''')
fw('\n\t\t\t\tTypedIndex: %i' % i)
fw('\n\t\t\t}')
if len(collayers) > 1:
# Take into account any UV layers
layer_offset = 0
if uvlayers:
layer_offset = len(uvlayers) - 1
for i in range(layer_offset, len(collayers) + layer_offset):
fw('\n\t\tLayer: %i {' % i)
fw('\n\t\t\tVersion: 100')
Campbell Barton
committed
LayerElement: {
Type: "LayerElementColor"''')
fw('\n\t\t\t\tTypedIndex: %i' % i)
fw('\n\t\t\t}')
fw('\n\t\t}')
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
if do_shapekeys:
key_blocks = my_mesh.blenObject.data.shape_keys.key_blocks[:]
for kb in key_blocks[1:]:
fw('\n\t\tShape: "%s" {' % kb.name)
fw('\n\t\t\tIndexes: ')
basis_verts = key_blocks[0].data
range_verts = []
delta_verts = []
i = -1
for j, kv in enumerate(kb.data):
delta = kv.co - basis_verts[j].co
if delta.length > 0.000001:
if i == -1:
fw('%d' % j)
else:
if i == 7:
fw('\n\t\t\t')
i = 0
fw(',%d' % j)
delta_verts.append(delta[:])
i += 1
fw('\n\t\t\tVertices: ')
i = -1
for dv in delta_verts:
if i == -1:
else:
if i == 4:
fw('\n\t\t\t')
i = 0
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
i += 1
# all zero, why? - campbell
fw('\n\t\t\tNormals: ')
for j in range(len(delta_verts)):
if i == -1:
fw("0,0,0")
else:
if i == 4:
fw('\n\t\t\t')
i = 0
fw(",0,0,0")
i += 1
fw('\n\t\t}')
for v in me_vertices:
if i == -1:
fw('%.6f,%.6f,%.6f' % v.co[:])
i = 0
else:
if i == 7:
fw('\n\t\t')
i = 0
fw(',%.6f,%.6f,%.6f' % v.co[:])
i += 1
def write_group(name):
fw('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name)
Campbell Barton
committed
Properties60: {
Property: "MultiLayer", "bool", "",0
Property: "Pickable", "bool", "",1
Property: "Transformable", "bool", "",1
Property: "Show", "bool", "",1
}
MultiLayer: 0
}''')
# add meshes here to clear because they are not used anywhere.
meshes_to_clear = []
ob_meshes = []
ob_lights = []
ob_cameras = []
# in fbx we export bones as children of the mesh
# armatures not a part of a mesh, will be added to ob_arms
ob_bones = []
ob_arms = []
ob_null = [] # emptys
# List of types that have blender objects (not bones)
ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null]
groups = [] # blender groups, only add ones that have objects in the selections
materials = {} # (mat, image) keys, should be a set()
textures = {} # should be a set()
tmp_ob_type = None # incase no objects are exported, so as not to raise an error
Campbell Barton
committed
if 'ARMATURE' in object_types:
# This is needed so applying modifiers dosnt apply the armature deformation, its also needed
# ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes.
# set every armature to its rest, backup the original values so we done mess up the scene
ob_arms_orig_rest = [arm.pose_position for arm in bpy.data.armatures]
for arm in bpy.data.armatures:
arm.pose_position = 'REST'
if ob_arms_orig_rest:
for ob_base in bpy.data.objects:
if ob_base.type == 'ARMATURE':
# This causes the makeDisplayList command to effect the mesh
scene.frame_set(scene.frame_current)
# ignore dupli children
if ob_base.parent and ob_base.parent.dupli_type in {'VERTS', 'FACES'}:
continue
obs = [(ob_base, ob_base.matrix_world.copy())]
if ob_base.dupli_type != 'NONE':
obs = [(dob.object, dob.matrix.copy()) for dob in ob_base.dupli_list]
for ob, mtx in obs:
tmp_ob_type = ob.type
if tmp_ob_type == 'CAMERA':
Campbell Barton
committed
if 'CAMERA' in object_types:
ob_cameras.append(my_object_generic(ob, mtx))
elif tmp_ob_type == 'LAMP':
Campbell Barton
committed
if 'LAMP' in object_types:
ob_lights.append(my_object_generic(ob, mtx))
elif tmp_ob_type == 'ARMATURE':
Campbell Barton
committed
if 'ARMATURE' in object_types:
# TODO - armatures dont work in dupligroups!
if ob not in ob_arms:
ob_arms.append(ob)
# ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)"
elif tmp_ob_type == 'EMPTY':
Campbell Barton
committed
if 'EMPTY' in object_types:
ob_null.append(my_object_generic(ob, mtx))
Campbell Barton
committed
elif 'MESH' in object_types:
origData = True
if tmp_ob_type != 'MESH':
try:
me = ob.to_mesh(scene, True, 'PREVIEW')
except:
me = None
if me:
meshes_to_clear.append(me)
mats = me.materials
origData = False
else:
# Mesh Type!
if use_mesh_modifiers:
me = ob.to_mesh(scene, True, 'PREVIEW')
# print ob, me, me.getVertGroupNames()
meshes_to_clear.append(me)
origData = False
mats = me.materials
else:
me = ob.data
mats = me.materials
# # Support object colors
# tmp_colbits = ob.colbits
# if tmp_colbits:
# tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too.
# for i in xrange(16):
# if tmp_colbits & (1<<i):
# mats[i] = tmp_ob_mats[i]
# del tmp_ob_mats
# del tmp_colbits
if me:
# # This WILL modify meshes in blender if use_mesh_modifiers is disabled.
# # so strictly this is bad. but only in rare cases would it have negative results
# # say with dupliverts the objects would rotate a bit differently
# if EXP_MESH_HQ_NORMALS:
# BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
texture_mapping_local = {}
material_mapping_local = {}
if me.uv_textures:
for uvlayer in me.uv_textures:
for f, uf in zip(me.faces, uvlayer.data):
tex = uf.image
textures[tex] = texture_mapping_local[tex] = None
try:
mat = mats[f.material_index]
except:
mat = None
materials[mat, tex] = material_mapping_local[mat, tex] = None # should use sets, wait for blender 2.5
else:
for mat in mats:
# 2.44 use mat.lib too for uniqueness
materials[mat, None] = material_mapping_local[mat, None] = None
else:
materials[None, None] = None
Campbell Barton
committed
if 'ARMATURE' in object_types:
armob = ob.find_armature()
blenParentBoneName = None
# parent bone - special case
if (not armob) and ob.parent and ob.parent.type == 'ARMATURE' and \
ob.parent_type == 'BONE':
armob = ob.parent
blenParentBoneName = ob.parent_bone
if armob and armob not in ob_arms: