Newer
Older
Campbell Barton
committed
do_light = not (light.use_only_shadow or (not light.use_diffuse and not light.use_specular))
do_shadow = (light.shadow_method in {'RAY_SHADOW', 'BUFFER_SHADOW'})
# scale = abs(global_matrix.to_scale()[0]) # scale is always uniform in this case # UNUSED
fw('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
fw('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
fw('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
fw('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
fw('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
fw('\n\t\t\tProperty: "GoboProperty", "object", ""')
fw('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1')
if light.type == 'SPOT':
fw('\n\t\t\tProperty: "OuterAngle", "Number", "A+",%.2f' %
math.degrees(light.spot_size))
fw('\n\t\t\tProperty: "InnerAngle", "Number", "A+",%.2f' %
(math.degrees(light.spot_size) - math.degrees(light.spot_size) * light.spot_blend))
fw('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
fw('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.color))
fw('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (light.energy * 100.0))
fw('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
fw('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
fw('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light)
fw('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
fw('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
fw('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
fw('\n\t\t\tProperty: "GoboProperty", "object", ""')
if light.type in {'SPOT', 'POINT'}:
if light.falloff_type == 'CONSTANT':
fw('\n\t\t\tProperty: "DecayType", "enum", "",0')
if light.falloff_type == 'INVERSE_LINEAR':
fw('\n\t\t\tProperty: "DecayType", "enum", "",1')
fw('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",1')
fw('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",%.2f' % (light.distance * 2.0))
if light.falloff_type == 'INVERSE_SQUARE':
fw('\n\t\t\tProperty: "DecayType", "enum", "",2')
fw('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",1')
fw('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",%.2f' % (light.distance * 2.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_dif = mat.diffuse_intensity
mat_amb = mat.ambient
mat_hard = ((float(mat.specular_hardness) - 1.0) / 510.0) * 128.0
mat_spec = mat.specular_intensity
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_cold = 0.8, 0.8, 0.8
mat_cols = 1.0, 1.0, 1.0
mat_colamb = 1.0, 1.0, 1.0
# mat_colm
mat_dif = 0.8
mat_amb = 1.0
mat_hard = 12.3
mat_spec = 0.5
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", "",%.1f' % mat_hard)
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:
fname_rel = bpy_extras.io_utils.path_reference(tex.filepath, base_src, base_dst, path_mode, "", copy_set, tex.library)
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:
fname_rel = bpy_extras.io_utils.path_reference(tex.filepath, base_src, base_dst, path_mode, "", copy_set, tex.library)
fname_strip = bpy.path.basename(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 specific 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
# Set TransformLink to the global transform of the bone and Transform
# equal to the mesh's transform in bone space.
# http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/why-the-values-return-by-fbxcluster-gettransformmatrix-x-not-same-with-the-value-in-ascii-fbx-file/
global_bone_matrix = (my_bone.fbxArm.matrixWorld * my_bone.restMatrix) * mtx4_z90
global_mesh_matrix = my_mesh.matrixWorld
transform_matrix = (global_bone_matrix.inverted() * global_mesh_matrix)
global_bone_matrix_string = mat4x4str(global_bone_matrix )
transform_matrix_string = mat4x4str(transform_matrix )
fw('\n\t\tTransform: %s' % transform_matrix_string)
fw('\n\t\tTransformLink: %s' % global_bone_matrix_string)
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.tessface_uv_textures)
do_shapekeys = (my_mesh.blenObject.type == 'MESH' and
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 ()
Campbell Barton
committed
me_faces = me.tessfaces[:]
poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3]
# Calculate the global transform for the mesh in the bind pose the same way we do
# in write_sub_deformer_skin
globalMeshBindPose = my_mesh.matrixWorld * mtx4_z90
pose_items.append((my_mesh.fbxName, globalMeshBindPose))
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:
Campbell Barton
committed
if i == -1:
fw('%i,%i' % (ed.vertices[0], ed.vertices[1]))
i = 0
else:
if i == 13:
fw('\n\t\t')
i = 0
Campbell Barton
committed
fw(',%i,%i' % (ed.vertices[0], ed.vertices[1]))
i += 1
LayerElementNormal: 0 {
Version: 101
Name: ""
MappingInformationType: "ByPolygonVertex"
ReferenceInformationType: "Direct"
Normals: ''')
# this could be compacted further
i = -1
for f in me_faces:
fi = f.vertices[:]
if i != -1:
fw(',') # ack!
elif i == 2:
fw('\n\t\t\t ')
i = 0
if f.use_smooth:
fw('%.6f,%.6f,%.6f' % me_vertices[fi[0]].normal[:])
fw(',%.6f,%.6f,%.6f' % me_vertices[fi[1]].normal[:])
fw(',%.6f,%.6f,%.6f' % me_vertices[fi[2]].normal[:])
if len(fi) == 4:
fw(',%.6f,%.6f,%.6f' % me_vertices[fi[3]].normal[:])
else:
f_no = f.normal[:]
fw('%.6f,%.6f,%.6f' % f_no)
fw(',%.6f,%.6f,%.6f' % f_no)
fw(',%.6f,%.6f,%.6f' % f_no)
if len(fi) == 4:
fw(',%.6f,%.6f,%.6f' % f_no)
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:
fw('%i' % (not ed.use_edge_sharp))
i = 0
Campbell Barton
committed
else:
if i == 54:
Campbell Barton
committed
i = 0
fw(',%i' % (not ed.use_edge_sharp))
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.tessface_vertex_colors):
collayers = me.tessface_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
print(len(me_faces), len(collayer.data))
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.tessface_uv_textures
for uvindex, uvlayer in enumerate(me.tessface_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.tessface_uv_textures.active:
uv_faces = me.tessface_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.tessface_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}')
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
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
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}')
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 # in case 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
me.update(calc_tessface=True)
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: