export_cal3d - exporting all actions (option) wasnt working
export_fbx - blender cameras now work properly (converted lens angle, rotate to the right axis) Made meshes, armatures and cameras use the same namespace. DirectX8Exporter - update from David Teviotdale, change names of exported objects so some DX readers dont fail xsi_export - Null materials made the export fail (python error). This may not be a correct solution since material indicies could be messed up now. I have no way of reading these files.
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
#!BPY
|
#!BPY
|
||||||
|
|
||||||
""" Registration info for Blender menus:
|
|
||||||
Name: 'DirectX(.x)...'
|
|
||||||
Blender: 242
|
|
||||||
Group: 'Export'
|
|
||||||
Tip: 'Export to DirectX text file format format.'
|
|
||||||
"""
|
"""
|
||||||
__author__ = "Arben (Ben) Omari"
|
# Name: 'DirectX (.x)...'
|
||||||
__url__ = ("blender", "elysiun", "Author's site, http://www.omariben.too.it")
|
# Blender: 242
|
||||||
|
# Group: 'Export'
|
||||||
|
# Tooltip: 'Export to DirectX text file format format for XNA Animation Component Library.'
|
||||||
|
"""
|
||||||
|
__author__ = "minahito (original:Arben (Ben) Omari)"
|
||||||
|
__url__ = ("blender", "elysiun", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it")
|
||||||
__version__ = "3.0"
|
__version__ = "3.0"
|
||||||
|
|
||||||
__bpydoc__ = """\
|
__bpydoc__ = """\
|
||||||
@@ -36,6 +36,10 @@ DX exporter.
|
|||||||
|
|
||||||
# Grab the latest version here :www.omariben.too.it
|
# Grab the latest version here :www.omariben.too.it
|
||||||
|
|
||||||
|
# [Notice]
|
||||||
|
# This script is the custom version of Mr.Arben Omari's great work.
|
||||||
|
# If you have a question about the adjusted part, visit http://sunday-lab.blogspot.com/.
|
||||||
|
|
||||||
import Blender
|
import Blender
|
||||||
from Blender import Types, Object, NMesh, Material,Armature,Mesh
|
from Blender import Types, Object, NMesh, Material,Armature,Mesh
|
||||||
from Blender.Mathutils import *
|
from Blender.Mathutils import *
|
||||||
@@ -61,6 +65,16 @@ toggle6_val = 0
|
|||||||
toggle7_val = 0
|
toggle7_val = 0
|
||||||
anim_tick = Draw.Create(25)
|
anim_tick = Draw.Create(25)
|
||||||
|
|
||||||
|
#***********************************************
|
||||||
|
# DirectX file spec only allows letters, digits, and
|
||||||
|
# underscore in Names.
|
||||||
|
#***********************************************
|
||||||
|
def make_legal_name(starting_name):
|
||||||
|
new_name = starting_name.replace('.','_')
|
||||||
|
new_name = new_name.replace(' ','_')
|
||||||
|
if new_name[0].isdigit():
|
||||||
|
new_name = '_' + new_name
|
||||||
|
return new_name
|
||||||
|
|
||||||
#***********************************************
|
#***********************************************
|
||||||
# MAIN
|
# MAIN
|
||||||
@@ -278,8 +292,6 @@ def rectFill(x,y,width,height):
|
|||||||
Draw.Register(draw, event, button_event)
|
Draw.Register(draw, event, button_event)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#***********************************************
|
#***********************************************
|
||||||
#***********************************************
|
#***********************************************
|
||||||
# EXPORTER
|
# EXPORTER
|
||||||
@@ -332,9 +344,7 @@ class xExport:
|
|||||||
if obj.type == "Empty" :
|
if obj.type == "Empty" :
|
||||||
mat = self.getLocMat(obj)
|
mat = self.getLocMat(obj)
|
||||||
mat_c = Matrix(mat)
|
mat_c = Matrix(mat)
|
||||||
name = obj.name
|
self.writeArmFrames(mat_c, make_legal_name(obj.name))
|
||||||
name_f = name.replace(".","")
|
|
||||||
self.writeArmFrames(mat_c, name_f)
|
|
||||||
if type(mesh) == Types.ArmatureType :
|
if type(mesh) == Types.ArmatureType :
|
||||||
Child_obj = self.getArmChildren(obj)
|
Child_obj = self.getArmChildren(obj)
|
||||||
chld_obj = obj
|
chld_obj = obj
|
||||||
@@ -384,6 +394,8 @@ class xExport:
|
|||||||
self.writeObjFrames(obj)
|
self.writeObjFrames(obj)
|
||||||
ch_l = self.getChildren(obj)
|
ch_l = self.getChildren(obj)
|
||||||
for ch in ch_l:
|
for ch in ch_l:
|
||||||
|
|
||||||
|
|
||||||
if ch and ch.type == "Armature":
|
if ch and ch.type == "Armature":
|
||||||
ch_list.append(ch)
|
ch_list.append(ch)
|
||||||
self.writeObjFrames(ch)
|
self.writeObjFrames(ch)
|
||||||
@@ -396,7 +408,7 @@ class xExport:
|
|||||||
|
|
||||||
self.file.write("} // End of the Root Frame\n")
|
self.file.write("} // End of the Root Frame\n")
|
||||||
if anim :
|
if anim :
|
||||||
self.file.write("AnimationSet {\n")
|
self.file.write("AnimationSet AnimationSet0 {\n")
|
||||||
for obj in Blender.Scene.GetCurrent().objects:
|
for obj in Blender.Scene.GetCurrent().objects:
|
||||||
if obj.type in ('Mesh', 'Empty'):
|
if obj.type in ('Mesh', 'Empty'):
|
||||||
ip_list = obj.ipo
|
ip_list = obj.ipo
|
||||||
@@ -432,7 +444,7 @@ class xExport:
|
|||||||
self.writeMeshMaterialList(obj, mesh, tex)
|
self.writeMeshMaterialList(obj, mesh, tex)
|
||||||
self.writeMeshNormals(obj, mesh)
|
self.writeMeshNormals(obj, mesh)
|
||||||
self.writeMeshTextureCoords(obj, mesh)
|
self.writeMeshTextureCoords(obj, mesh)
|
||||||
self.file.write(" } // End of the Frame %s \n" % (obj.name))
|
self.file.write(" } // End of the Mesh %s \n" % (obj.name))
|
||||||
|
|
||||||
|
|
||||||
#***********************************************
|
#***********************************************
|
||||||
@@ -459,7 +471,7 @@ class xExport:
|
|||||||
self.file.write("}\n")
|
self.file.write("}\n")
|
||||||
ip_list = obj.ipo
|
ip_list = obj.ipo
|
||||||
if ip_list != None :
|
if ip_list != None :
|
||||||
self.file.write("AnimationSet {\n")
|
self.file.write("AnimationSet AnimationSet0 {\n")
|
||||||
self.writeAnimationObj(obj)
|
self.writeAnimationObj(obj)
|
||||||
self.file.write("}\n")
|
self.file.write("}\n")
|
||||||
else :
|
else :
|
||||||
@@ -494,9 +506,8 @@ class xExport:
|
|||||||
root_bon = bon
|
root_bon = bon
|
||||||
space += 1
|
space += 1
|
||||||
mat_r = self.writeAnimCombineMatrix(root_bon,1)
|
mat_r = self.writeAnimCombineMatrix(root_bon,1)
|
||||||
name_r = root_bon.name
|
self.writeArmFrames(mat_r, make_legal_name(root_bon.name))
|
||||||
name_f = name_r.replace(".","")
|
|
||||||
self.writeArmFrames(mat_r, name_f)
|
|
||||||
bon_c = root_bon.children
|
bon_c = root_bon.children
|
||||||
self.writeChildren(bon_c)
|
self.writeChildren(bon_c)
|
||||||
self.file.write(" } // End of the Bone %s \n" % (root_bon.name))
|
self.file.write(" } // End of the Bone %s \n" % (root_bon.name))
|
||||||
@@ -508,9 +519,7 @@ class xExport:
|
|||||||
def writeBon(self,bon):
|
def writeBon(self,bon):
|
||||||
global space
|
global space
|
||||||
mat_r = self.writeAnimCombineMatrix(bon,1)
|
mat_r = self.writeAnimCombineMatrix(bon,1)
|
||||||
name_r = bon.name
|
self.writeArmFrames(mat_r, make_legal_name(bon.name))
|
||||||
name_f = name_r.replace(".","")
|
|
||||||
self.writeArmFrames(mat_r, name_f)
|
|
||||||
|
|
||||||
|
|
||||||
def writeChildren(self,bon_c):
|
def writeChildren(self,bon_c):
|
||||||
@@ -627,7 +636,7 @@ class xExport:
|
|||||||
bo_list = []
|
bo_list = []
|
||||||
weight_list = []
|
weight_list = []
|
||||||
name = bo.name
|
name = bo.name
|
||||||
f_name = name.replace(".","")
|
f_name = make_legal_name(name)
|
||||||
try :
|
try :
|
||||||
vert_list = mesh.getVertsFromGroup(name,1)
|
vert_list = mesh.getVertsFromGroup(name,1)
|
||||||
le = 0
|
le = 0
|
||||||
@@ -771,9 +780,7 @@ template SkinWeights {\n\
|
|||||||
global index_list,flip_z
|
global index_list,flip_z
|
||||||
#TransformMatrix
|
#TransformMatrix
|
||||||
mat = self.getLocMat(obj)
|
mat = self.getLocMat(obj)
|
||||||
name_f = obj.name.replace(".","")
|
self.writeArmFrames(mat, make_legal_name(obj.name))
|
||||||
name_f = name_f.replace(" ","")
|
|
||||||
self.writeArmFrames(mat, name_f)
|
|
||||||
mesh = NMesh.GetRawFromObject(obj.name)
|
mesh = NMesh.GetRawFromObject(obj.name)
|
||||||
self.file.write("Mesh {\n")
|
self.file.write("Mesh {\n")
|
||||||
numface=len(mesh.faces)
|
numface=len(mesh.faces)
|
||||||
@@ -815,23 +822,14 @@ template SkinWeights {\n\
|
|||||||
coun,counter = 0, 0
|
coun,counter = 0, 0
|
||||||
for face in mesh.faces :
|
for face in mesh.faces :
|
||||||
coun += 1
|
coun += 1
|
||||||
|
separator = ','
|
||||||
if coun == numface:
|
if coun == numface:
|
||||||
|
separator = ';'
|
||||||
if len(face.v) == 3:
|
if len(face.v) == 3:
|
||||||
self.file.write("3; %d, %d, %d;;\n" % (counter + a3, counter + b3, counter + c3))
|
self.file.write("3; %d, %d, %d;%c\n" % (counter + a3, counter + b3, counter + c3, separator))
|
||||||
counter += 3
|
counter += 3
|
||||||
elif len(face.v) == 4:
|
elif len(face.v) == 4:
|
||||||
self.file.write("4; %d, %d, %d, %d;;\n" % (counter + a4, counter + b4, counter + c4, counter + d4))
|
self.file.write("4; %d, %d, %d, %d;%c\n" % (counter + a4, counter + b4, counter + c4, counter + d4, separator))
|
||||||
counter += 4
|
|
||||||
elif len(face.v) < 3:
|
|
||||||
print "WARNING:the mesh has faces with less then 3 vertices"
|
|
||||||
print " It my be not exported correctly."
|
|
||||||
else:
|
|
||||||
|
|
||||||
if len(face.v) == 3:
|
|
||||||
self.file.write("3; %d, %d, %d;,\n" % (counter + a3, counter + b3, counter + c3))
|
|
||||||
counter += 3
|
|
||||||
elif len(face.v) == 4:
|
|
||||||
self.file.write("4; %d, %d, %d, %d;,\n" % (counter + a4, counter + b4, counter + c4, counter + d4))
|
|
||||||
counter += 4
|
counter += 4
|
||||||
elif len(face.v) < 3:
|
elif len(face.v) < 3:
|
||||||
print "WARNING:the mesh has faces with less then 3 vertices"
|
print "WARNING:the mesh has faces with less then 3 vertices"
|
||||||
@@ -870,9 +868,7 @@ template SkinWeights {\n\
|
|||||||
##MATERIAL NAME
|
##MATERIAL NAME
|
||||||
for mat in mesh.getMaterials():
|
for mat in mesh.getMaterials():
|
||||||
self.file.write(" Material")
|
self.file.write(" Material")
|
||||||
name_m = mat.name
|
self.file.write(" %s "% (make_legal_name(mat.name)))
|
||||||
name_f = name_m.replace(".","")
|
|
||||||
self.file.write(" %s "% (name_f))
|
|
||||||
self.file.write("{\n")
|
self.file.write("{\n")
|
||||||
self.file.write(" %f; %f; %f;" % (mat.R, mat.G, mat.B))
|
self.file.write(" %f; %f; %f;" % (mat.R, mat.G, mat.B))
|
||||||
self.file.write("%s;;\n" % (mat.alpha))
|
self.file.write("%s;;\n" % (mat.alpha))
|
||||||
@@ -1081,7 +1077,7 @@ template SkinWeights {\n\
|
|||||||
for bon in arm.bones.values() :
|
for bon in arm.bones.values() :
|
||||||
point_list = []
|
point_list = []
|
||||||
name = bon.name
|
name = bon.name
|
||||||
name_f = name.replace(".", "")
|
name_f = make_legal_name(name)
|
||||||
try :
|
try :
|
||||||
ip_bon_channel = ip[bon.name]
|
ip_bon_channel = ip[bon.name]
|
||||||
ip_bon_name = ip_bon_channel.getName()
|
ip_bon_name = ip_bon_channel.getName()
|
||||||
@@ -1139,11 +1135,9 @@ template SkinWeights {\n\
|
|||||||
a = po.getPoints()
|
a = po.getPoints()
|
||||||
point_list.append(int(a[0]))
|
point_list.append(int(a[0]))
|
||||||
|
|
||||||
name = obj.name
|
|
||||||
name_f = name.replace(".", "")
|
|
||||||
self.file.write(" Animation {\n")
|
self.file.write(" Animation {\n")
|
||||||
self.file.write(" { ")
|
self.file.write(" { ")
|
||||||
self.file.write("%s }\n" % (name_f))
|
self.file.write("%s }\n" % (make_legal_name(obj.name)))
|
||||||
self.file.write(" AnimationKey { \n")
|
self.file.write(" AnimationKey { \n")
|
||||||
self.file.write(" 4;\n")
|
self.file.write(" 4;\n")
|
||||||
self.file.write(" %d; \n" % (len(point_list)))
|
self.file.write(" %d; \n" % (len(point_list)))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!BPY
|
#!BPY
|
||||||
"""
|
"""
|
||||||
Name: 'Cal3D XML (.cfg)...'
|
Name: 'Cal3D (.cfg .xaf .xsf .xmf .xrf)...'
|
||||||
Blender: 243
|
Blender: 243
|
||||||
Group: 'Export'
|
Group: 'Export'
|
||||||
Tip: 'Export armature/bone/mesh/action data to the Cal3D format.'
|
Tip: 'Export armature/bone/mesh/action data to the Cal3D format.'
|
||||||
@@ -386,7 +386,7 @@ class Cal3DMesh(object):
|
|||||||
if len(uvlayers)>1:
|
if len(uvlayers)>1:
|
||||||
for i, blend_vert in enumerate(face_v):
|
for i, blend_vert in enumerate(face_v):
|
||||||
if face.smooth: normal = blend_vert.no
|
if face.smooth: normal = blend_vert.no
|
||||||
vertex = submesh.getVertex(blend_mesh, blend_vert.index, blend_vert.co, normal, face_multi_uvs[face.index][i])
|
vertex = submesh.getVertex(blend_mesh, blend_vert, normal, face_multi_uvs[face.index][i])
|
||||||
face_vertices.append(vertex)
|
face_vertices.append(vertex)
|
||||||
|
|
||||||
elif len(uvlayers)==1:
|
elif len(uvlayers)==1:
|
||||||
@@ -398,13 +398,13 @@ class Cal3DMesh(object):
|
|||||||
if write_single_layer_uvs: uvs = (tuple(face_uv[i]),)
|
if write_single_layer_uvs: uvs = (tuple(face_uv[i]),)
|
||||||
else: uvs = ()
|
else: uvs = ()
|
||||||
|
|
||||||
vertex = submesh.getVertex(blend_mesh, blend_vert.index, blend_vert.co, normal, uvs )
|
vertex = submesh.getVertex(blend_mesh, blend_vert, normal, uvs )
|
||||||
face_vertices.append(vertex)
|
face_vertices.append(vertex)
|
||||||
else:
|
else:
|
||||||
# No UVs
|
# No UVs
|
||||||
for i, blend_vert in enumerate(face_v):
|
for i, blend_vert in enumerate(face_v):
|
||||||
if face.smooth: normal = blend_vert.no
|
if face.smooth: normal = blend_vert.no
|
||||||
vertex = submesh.getVertex(blend_mesh, blend_vert.index, blend_vert.co, normal, () )
|
vertex = submesh.getVertex(blend_mesh, blend_vert, normal, () )
|
||||||
face_vertices.append(vertex)
|
face_vertices.append(vertex)
|
||||||
|
|
||||||
|
|
||||||
@@ -433,12 +433,15 @@ class Cal3DSubMesh(object):
|
|||||||
self.springs = []
|
self.springs = []
|
||||||
self.id = id
|
self.id = id
|
||||||
|
|
||||||
def getVertex(self, blend_mesh, blend_index, loc, normal, maps):
|
def getVertex(self, blend_mesh, blend_vert, normal, maps):
|
||||||
|
'''
|
||||||
|
Request a vertex, and create a new one or return a matching vertex
|
||||||
|
'''
|
||||||
|
blend_index = blend_vert.index
|
||||||
index_map = self.vert_mapping.get(blend_index)
|
index_map = self.vert_mapping.get(blend_index)
|
||||||
|
|
||||||
if index_map == None:
|
if index_map == None:
|
||||||
vertex = Cal3DVertex(loc, normal, maps, blend_mesh.getVertexInfluences(blend_index))
|
vertex = Cal3DVertex(blend_vert.co, normal, maps, blend_mesh.getVertexInfluences(blend_index))
|
||||||
self.vertices.append([vertex])
|
self.vertices.append([vertex])
|
||||||
self.vert_mapping[blend_index] = len(self.vert_mapping)
|
self.vert_mapping[blend_index] = len(self.vert_mapping)
|
||||||
self.vert_count +=1
|
self.vert_count +=1
|
||||||
@@ -453,7 +456,7 @@ class Cal3DSubMesh(object):
|
|||||||
|
|
||||||
# No match, add a new vert
|
# No match, add a new vert
|
||||||
# Use the first verts influences
|
# Use the first verts influences
|
||||||
vertex = Cal3DVertex(loc, normal, maps, vertex_list[0].influences)
|
vertex = Cal3DVertex(blend_vert.co, normal, maps, vertex_list[0].influences)
|
||||||
vertex_list.append(vertex)
|
vertex_list.append(vertex)
|
||||||
# self.vert_mapping[blend_index] = len(self.vert_mapping)
|
# self.vert_mapping[blend_index] = len(self.vert_mapping)
|
||||||
self.vert_count +=1
|
self.vert_count +=1
|
||||||
@@ -899,7 +902,9 @@ def export_cal3d(filename, PREF_SCALE=0.1, PREF_BAKE_MOTION = True, PREF_ACT_ACT
|
|||||||
SUPPORTED_IPOS = 'QuatW', 'QuatX', 'QuatY', 'QuatZ', 'LocX', 'LocY', 'LocZ'
|
SUPPORTED_IPOS = 'QuatW', 'QuatX', 'QuatY', 'QuatZ', 'LocX', 'LocY', 'LocZ'
|
||||||
|
|
||||||
if PREF_ACT_ACTION_ONLY: action_items = [(blender_armature.action.name, blender_armature.action)]
|
if PREF_ACT_ACTION_ONLY: action_items = [(blender_armature.action.name, blender_armature.action)]
|
||||||
else: action_items = Blender.Armature.NLA.GetActions().iteritems()
|
else: action_items = Blender.Armature.NLA.GetActions().items()
|
||||||
|
|
||||||
|
print len(action_items), 'action_items'
|
||||||
|
|
||||||
for animation_name, blend_action in action_items:
|
for animation_name, blend_action in action_items:
|
||||||
|
|
||||||
@@ -913,9 +918,10 @@ def export_cal3d(filename, PREF_SCALE=0.1, PREF_BAKE_MOTION = True, PREF_ACT_ACT
|
|||||||
action_end= max(_frames);
|
action_end= max(_frames);
|
||||||
del _frames
|
del _frames
|
||||||
|
|
||||||
|
blender_armature.action = blend_action
|
||||||
|
|
||||||
if PREF_BAKE_MOTION:
|
if PREF_BAKE_MOTION:
|
||||||
# We need to set the action active if we are getting baked data
|
# We need to set the action active if we are getting baked data
|
||||||
blend_action.setActive(blender_armature)
|
|
||||||
pose_data = BPyArmature.getBakedPoseData(blender_armature, action_start, action_end)
|
pose_data = BPyArmature.getBakedPoseData(blender_armature, action_start, action_end)
|
||||||
|
|
||||||
# Fake, all we need is bone names
|
# Fake, all we need is bone names
|
||||||
@@ -932,6 +938,8 @@ def export_cal3d(filename, PREF_SCALE=0.1, PREF_BAKE_MOTION = True, PREF_ACT_ACT
|
|||||||
blend_action_ipos_items.append( (bone_name, []) )
|
blend_action_ipos_items.append( (bone_name, []) )
|
||||||
|
|
||||||
animation = Cal3DAnimation(animation_name)
|
animation = Cal3DAnimation(animation_name)
|
||||||
|
# ----------------------------
|
||||||
|
ANIMATIONS.append(animation)
|
||||||
animation.duration = 0.0
|
animation.duration = 0.0
|
||||||
|
|
||||||
for bone_name, ipo in blend_action_ipos_items:
|
for bone_name, ipo in blend_action_ipos_items:
|
||||||
@@ -1018,15 +1026,13 @@ def export_cal3d(filename, PREF_SCALE=0.1, PREF_BAKE_MOTION = True, PREF_ACT_ACT
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Restore the original armature
|
# Restore the original armature
|
||||||
backup_action.setActive(blender_armature)
|
blender_armature.action = backup_action
|
||||||
|
# ------------------------------------- End Animation
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
ANIMATIONS.append(animation)
|
|
||||||
|
|
||||||
|
|
||||||
cfg = open((filename), 'wb')
|
cfg = open((filename), 'wb')
|
||||||
cfg.write('# Cal3D model exported from Blender with export_cal3d.py\n')
|
cfg.write('# Cal3D model exported from Blender with export_cal3d.py\n# from %s\n' % Blender.Get('filename'))
|
||||||
|
|
||||||
if PREF_SCALE != 1.0: cfg.write('scale=%.6f\n' % PREF_SCALE)
|
if PREF_SCALE != 1.0: cfg.write('scale=%.6f\n' % PREF_SCALE)
|
||||||
|
|
||||||
@@ -1099,6 +1105,8 @@ def export_cal3d_ui(filename):
|
|||||||
#import os
|
#import os
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
Blender.Window.FileSelector(export_cal3d_ui, 'Cal3D Export', Blender.Get('filename').replace('.blend', '.cfg'))
|
Blender.Window.FileSelector(export_cal3d_ui, 'Cal3D Export', Blender.Get('filename').replace('.blend', '.cfg'))
|
||||||
|
#export_cal3d('/cally/data/skeleton/skeleton' + '.cfg', 1.0, True, False, False)
|
||||||
#export_cal3d('/test' + '.cfg')
|
#export_cal3d('/test' + '.cfg')
|
||||||
#export_cal3d_ui('/test' + '.cfg')
|
#export_cal3d_ui('/test' + '.cfg')
|
||||||
#os.system('cd /; wine /cal3d_miniviewer.exe /test.cfg')
|
#os.system('cd /; wine /cal3d_miniviewer.exe /skeleton.cfg')
|
||||||
|
#os.system('cd /cally/;wine cally')
|
||||||
|
|||||||
@@ -47,13 +47,12 @@ import BPyMesh
|
|||||||
import BPySys
|
import BPySys
|
||||||
import BPyMessages
|
import BPyMessages
|
||||||
import time
|
import time
|
||||||
from math import degrees
|
from math import degrees, atan, pi
|
||||||
# Used to add the scene name into the filename without using odd chars
|
# Used to add the scene name into the filename without using odd chars
|
||||||
|
|
||||||
sane_name_mapping_ob = {}
|
sane_name_mapping_ob = {}
|
||||||
sane_name_mapping_mat = {}
|
sane_name_mapping_mat = {}
|
||||||
sane_name_mapping_tex = {}
|
sane_name_mapping_tex = {}
|
||||||
sane_name_mapping_arm = {}
|
|
||||||
sane_name_mapping_cam = {}
|
|
||||||
|
|
||||||
def strip_path(p):
|
def strip_path(p):
|
||||||
return p.split('\\')[-1].split('/')[-1]
|
return p.split('\\')[-1].split('/')[-1]
|
||||||
@@ -72,8 +71,6 @@ def sane_name(data, dct):
|
|||||||
def sane_obname(data): return sane_name(data, sane_name_mapping_ob)
|
def sane_obname(data): return sane_name(data, sane_name_mapping_ob)
|
||||||
def sane_matname(data): return sane_name(data, sane_name_mapping_mat)
|
def sane_matname(data): return sane_name(data, sane_name_mapping_mat)
|
||||||
def sane_texname(data): return sane_name(data, sane_name_mapping_tex)
|
def sane_texname(data): return sane_name(data, sane_name_mapping_tex)
|
||||||
def sane_armname(data): return sane_name(data, sane_name_mapping_arm)
|
|
||||||
def sane_camname(data): return sane_name(data, sane_name_mapping_cam)
|
|
||||||
|
|
||||||
# May use this later
|
# May use this later
|
||||||
"""
|
"""
|
||||||
@@ -130,16 +127,25 @@ def write_scene(file, sce, world):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
if ob and not matrix: matrix = ob.matrixWorld
|
if ob and not matrix: matrix = ob.matrixWorld
|
||||||
|
matrix_rot = matrix
|
||||||
|
#if matrix:
|
||||||
|
# matrix = matrix_scale * matrix
|
||||||
|
|
||||||
if matrix:
|
if matrix:
|
||||||
loc = tuple(matrix.translationPart())
|
loc = tuple(matrix.translationPart())
|
||||||
scale = tuple(matrix.scalePart())
|
scale = tuple(matrix.scalePart())
|
||||||
|
|
||||||
|
matrix_rot = matrix.rotationPart()
|
||||||
# Lamps need to be rotated
|
# Lamps need to be rotated
|
||||||
if ob and ob.type =='Lamp':
|
if ob and ob.type =='Lamp':
|
||||||
matrix = Blender.Mathutils.RotationMatrix(90, 4, 'x') * matrix
|
matrix_rot = Blender.Mathutils.RotationMatrix(90, 4, 'x') * matrix
|
||||||
|
rot = tuple(matrix_rot.toEuler())
|
||||||
rot = tuple(matrix.rotationPart().toEuler())
|
elif ob and ob.type =='Camera':
|
||||||
|
y = Blender.Mathutils.Vector(0,1,0) * matrix_rot
|
||||||
|
matrix_rot = matrix_rot * Blender.Mathutils.RotationMatrix(90, 3, 'r', y)
|
||||||
|
rot = tuple(matrix_rot.toEuler())
|
||||||
|
else:
|
||||||
|
rot = tuple(matrix_rot.toEuler())
|
||||||
else:
|
else:
|
||||||
if not loc:
|
if not loc:
|
||||||
loc = 0,0,0
|
loc = 0,0,0
|
||||||
@@ -149,7 +155,7 @@ def write_scene(file, sce, world):
|
|||||||
file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc)
|
file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc)
|
||||||
file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot)
|
file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot)
|
||||||
file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale)
|
file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale)
|
||||||
return loc, rot, scale, matrix
|
return loc, rot, scale, matrix, matrix_rot
|
||||||
|
|
||||||
def write_object_props(ob=None, loc=None, matrix=None):
|
def write_object_props(ob=None, loc=None, matrix=None):
|
||||||
# if the type is 0 its an empty otherwise its a mesh
|
# if the type is 0 its an empty otherwise its a mesh
|
||||||
@@ -159,7 +165,7 @@ def write_scene(file, sce, world):
|
|||||||
Property: "QuaternionInterpolate", "bool", "",0
|
Property: "QuaternionInterpolate", "bool", "",0
|
||||||
Property: "Visibility", "Visibility", "A+",1''')
|
Property: "Visibility", "Visibility", "A+",1''')
|
||||||
|
|
||||||
loc, rot, scale, matrix = write_object_tx(ob, loc, matrix)
|
loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix)
|
||||||
|
|
||||||
# Rotation order
|
# Rotation order
|
||||||
# eEULER_XYZ
|
# eEULER_XYZ
|
||||||
@@ -240,7 +246,7 @@ def write_scene(file, sce, world):
|
|||||||
file.write('\n\t\t\tProperty: "Size", "double", "",100')
|
file.write('\n\t\t\tProperty: "Size", "double", "",100')
|
||||||
file.write('\n\t\t\tProperty: "Look", "enum", "",1')
|
file.write('\n\t\t\tProperty: "Look", "enum", "",1')
|
||||||
|
|
||||||
return loc, rot, scale, matrix
|
return loc, rot, scale, matrix, matrix_rot
|
||||||
|
|
||||||
def write_camera_switch():
|
def write_camera_switch():
|
||||||
file.write('''
|
file.write('''
|
||||||
@@ -374,12 +380,15 @@ def write_scene(file, sce, world):
|
|||||||
aspect = float(width)/height
|
aspect = float(width)/height
|
||||||
|
|
||||||
data = ob.data
|
data = ob.data
|
||||||
|
|
||||||
|
angle= 360.0 * atan(16.0/data.lens) / pi;
|
||||||
|
|
||||||
file.write('\n\tModel: "Model::%s", "Camera" {' % name )
|
file.write('\n\tModel: "Model::%s", "Camera" {' % name )
|
||||||
file.write('\n\t\tVersion: 232')
|
file.write('\n\t\tVersion: 232')
|
||||||
loc, rot, scale, matrix = write_object_props(ob)
|
loc, rot, scale, matrix, matrix_rot = write_object_props(ob)
|
||||||
|
|
||||||
file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0')
|
file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0')
|
||||||
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.lens)
|
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % angle)
|
||||||
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
|
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
|
||||||
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
|
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
|
||||||
file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
|
file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
|
||||||
@@ -464,8 +473,12 @@ def write_scene(file, sce, world):
|
|||||||
file.write('\n\t\tTypeFlags: "Camera"')
|
file.write('\n\t\tTypeFlags: "Camera"')
|
||||||
file.write('\n\t\tGeometryVersion: 124')
|
file.write('\n\t\tGeometryVersion: 124')
|
||||||
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
|
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
|
||||||
file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,1,0)*matrix) )
|
file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,1,0) * matrix_rot) )
|
||||||
file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,0,-1)*matrix) )
|
file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,0,-1)*matrix_rot) )
|
||||||
|
|
||||||
|
#file.write('\n\t\tUp: 0,0,0' )
|
||||||
|
#file.write('\n\t\tLookAt: 0,0,0' )
|
||||||
|
|
||||||
file.write('\n\t\tShowInfoOnMoving: 1')
|
file.write('\n\t\tShowInfoOnMoving: 1')
|
||||||
file.write('\n\t\tShowAudio: 0')
|
file.write('\n\t\tShowAudio: 0')
|
||||||
file.write('\n\t\tAudioColor: 0,1,0')
|
file.write('\n\t\tAudioColor: 0,1,0')
|
||||||
@@ -542,7 +555,7 @@ def write_scene(file, sce, world):
|
|||||||
if mat:
|
if mat:
|
||||||
mat_cold = tuple(mat.rgbCol)
|
mat_cold = tuple(mat.rgbCol)
|
||||||
mat_cols = tuple(mat.specCol)
|
mat_cols = tuple(mat.specCol)
|
||||||
#mat_colm = tuple(mat.mirCol)
|
#mat_colm = tuple(mat.mirCol) # we wont use the mirror color
|
||||||
mat_colamb = tuple([c for c in world_amb])
|
mat_colamb = tuple([c for c in world_amb])
|
||||||
|
|
||||||
mat_dif = mat.ref
|
mat_dif = mat.ref
|
||||||
@@ -700,7 +713,7 @@ def write_scene(file, sce, world):
|
|||||||
#for ob in [ob_base,]:
|
#for ob in [ob_base,]:
|
||||||
ob_type = ob.type
|
ob_type = ob.type
|
||||||
if ob_type == 'Camera':
|
if ob_type == 'Camera':
|
||||||
ob_cameras.append((sane_camname(ob), ob))
|
ob_cameras.append((sane_obname(ob), ob))
|
||||||
elif ob_type == 'Lamp':
|
elif ob_type == 'Lamp':
|
||||||
ob_lights.append((sane_obname(ob), ob))
|
ob_lights.append((sane_obname(ob), ob))
|
||||||
|
|
||||||
@@ -727,7 +740,7 @@ def write_scene(file, sce, world):
|
|||||||
arm = BPyObject.getObjectArmature(ob)
|
arm = BPyObject.getObjectArmature(ob)
|
||||||
|
|
||||||
if arm:
|
if arm:
|
||||||
armname = sane_armname(arm)
|
armname = sane_obname(arm)
|
||||||
bones = arm.bones.values()
|
bones = arm.bones.values()
|
||||||
armatures_totbones += len(bones)
|
armatures_totbones += len(bones)
|
||||||
armatures.append((arm, armname, bones))
|
armatures.append((arm, armname, bones))
|
||||||
@@ -1236,6 +1249,9 @@ Objects: {''')
|
|||||||
Relations: {''')
|
Relations: {''')
|
||||||
|
|
||||||
file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}')
|
file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}')
|
||||||
|
for obname, ob in ob_cameras:
|
||||||
|
file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % obname)
|
||||||
|
|
||||||
for obname, ob in ob_lights:
|
for obname, ob in ob_lights:
|
||||||
file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % obname)
|
file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % obname)
|
||||||
|
|
||||||
@@ -1280,6 +1296,9 @@ Connections: {''')
|
|||||||
# write the fake root node
|
# write the fake root node
|
||||||
file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"')
|
file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"')
|
||||||
|
|
||||||
|
for obname, ob in ob_cameras:
|
||||||
|
file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
|
||||||
|
|
||||||
for obname, ob in ob_lights:
|
for obname, ob in ob_lights:
|
||||||
file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
|
file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
|
||||||
|
|
||||||
@@ -1359,8 +1378,6 @@ def write_footer(file, sce, world):
|
|||||||
sane_name_mapping_ob.clear()
|
sane_name_mapping_ob.clear()
|
||||||
sane_name_mapping_mat.clear()
|
sane_name_mapping_mat.clear()
|
||||||
sane_name_mapping_tex.clear()
|
sane_name_mapping_tex.clear()
|
||||||
sane_name_mapping_arm.clear()
|
|
||||||
sane_name_mapping_cam.clear()
|
|
||||||
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
@@ -1368,8 +1385,8 @@ def write_ui(filename):
|
|||||||
if not filename.lower().endswith('.fbx'):
|
if not filename.lower().endswith('.fbx'):
|
||||||
filename += '.fbx'
|
filename += '.fbx'
|
||||||
|
|
||||||
if not BPyMessages.Warning_SaveOver(filename):
|
#if not BPyMessages.Warning_SaveOver(filename):
|
||||||
return
|
# return
|
||||||
sce = bpy.data.scenes.active
|
sce = bpy.data.scenes.active
|
||||||
world = sce.world
|
world = sce.world
|
||||||
|
|
||||||
@@ -1382,3 +1399,4 @@ def write_ui(filename):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx'))
|
Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx'))
|
||||||
|
#write_ui('/test.fbx')
|
||||||
|
|||||||
@@ -171,7 +171,10 @@ def get_materials(obj):
|
|||||||
mats.extend(obj.getData(mesh=1).materials)
|
mats.extend(obj.getData(mesh=1).materials)
|
||||||
|
|
||||||
# return the materials list
|
# return the materials list
|
||||||
return mats
|
|
||||||
|
# Is this correct!!?? - None materials raise an error otherwise
|
||||||
|
# but it might screw up the indicies.. TODO... check the exported files.
|
||||||
|
return [m for m in mats if m]
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# do_header writes out the header data
|
# do_header writes out the header data
|
||||||
|
|||||||
Reference in New Issue
Block a user