3
Name: 'Autodesk FBX (.fbx)...'
6
Tooltip: 'Selection to an ASCII Autodesk FBX '
8
__author__ = "Campbell Barton"
9
__url__ = ['www.blender.org', 'blenderartists.org']
13
This script is an exporter to the FBX file format.
17
Select the objects you wish to export and run this script from "File->Export" menu.
18
All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
19
will be exported as mesh data.
22
# --------------------------------------------------------------------------
23
# FBX Export v0.1 by Campbell Barton (AKA Ideasman)
24
# --------------------------------------------------------------------------
25
# ***** BEGIN GPL LICENSE BLOCK *****
27
# This program is free software; you can redistribute it and/or
28
# modify it under the terms of the GNU General Public License
29
# as published by the Free Software Foundation; either version 2
30
# of the License, or (at your option) any later version.
32
# This program is distributed in the hope that it will be useful,
33
# but WITHOUT ANY WARRANTY; without even the implied warranty of
34
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35
# GNU General Public License for more details.
37
# You should have received a copy of the GNU General Public License
38
# along with this program; if not, write to the Free Software Foundation,
39
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41
# ***** END GPL LICENCE BLOCK *****
42
# --------------------------------------------------------------------------
50
from math import degrees, atan, pi
51
# Used to add the scene name into the filename without using odd chars
53
sane_name_mapping_ob = {}
54
sane_name_mapping_mat = {}
55
sane_name_mapping_tex = {}
58
return p.split('\\')[-1].split('/')[-1]
60
def sane_name(data, dct):
61
if not data: return None
67
name = BPySys.cleanName(name)
71
def sane_obname(data): return sane_name(data, sane_name_mapping_ob)
72
def sane_matname(data): return sane_name(data, sane_name_mapping_mat)
73
def sane_texname(data): return sane_name(data, sane_name_mapping_tex)
77
# Auto class, use for datastorage only, a like a dictionary but with limited slots
78
def auto_class(slots):
79
exec('class container_class(object): __slots__=%s' % slots)
80
return container_class
85
'''; FBX 6.1.0 project file
86
; Created by Blender FBX Exporter
87
; for support mail cbarton@metavr.com
88
; ----------------------------------------------------
92
def write_header(file):
93
file.write(header_comment)
94
curtime = time.localtime()[0:6]
97
'''FBXHeaderExtension: {
98
FBXHeaderVersion: 1003
110
Creator: "FBX SDK/FBX Plugins build 20070228"
116
file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime)
117
file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version'))
122
def write_scene(file, sce, world):
124
def write_object_tx(ob, loc, matrix):
126
We have loc to set the location if non blender objects that have a location
129
if ob and not matrix: matrix = ob.matrixWorld
132
# matrix = matrix_scale * matrix
135
loc = tuple(matrix.translationPart())
136
scale = tuple(matrix.scalePart())
138
matrix_rot = matrix.rotationPart()
139
# Lamps need to be rotated
140
if ob and ob.type =='Lamp':
141
matrix_rot = Blender.Mathutils.RotationMatrix(90, 4, 'x') * matrix
142
rot = tuple(matrix_rot.toEuler())
143
elif ob and ob.type =='Camera':
144
y = Blender.Mathutils.Vector(0,1,0) * matrix_rot
145
matrix_rot = matrix_rot * Blender.Mathutils.RotationMatrix(90, 3, 'r', y)
146
rot = tuple(matrix_rot.toEuler())
148
rot = tuple(matrix_rot.toEuler())
155
file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc)
156
file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot)
157
file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale)
158
return loc, rot, scale, matrix, matrix_rot
160
def write_object_props(ob=None, loc=None, matrix=None):
161
# if the type is 0 its an empty otherwise its a mesh
162
# only difference at the moment is one has a color
165
Property: "QuaternionInterpolate", "bool", "",0
166
Property: "Visibility", "Visibility", "A+",1''')
168
loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix)
180
Property: "RotationOffset", "Vector3D", "",0,0,0
181
Property: "RotationPivot", "Vector3D", "",0,0,0
182
Property: "ScalingOffset", "Vector3D", "",0,0,0
183
Property: "ScalingPivot", "Vector3D", "",0,0,0
184
Property: "TranslationActive", "bool", "",0
185
Property: "TranslationMin", "Vector3D", "",0,0,0
186
Property: "TranslationMax", "Vector3D", "",0,0,0
187
Property: "TranslationMinX", "bool", "",0
188
Property: "TranslationMinY", "bool", "",0
189
Property: "TranslationMinZ", "bool", "",0
190
Property: "TranslationMaxX", "bool", "",0
191
Property: "TranslationMaxY", "bool", "",0
192
Property: "TranslationMaxZ", "bool", "",0
193
Property: "RotationOrder", "enum", "",1
194
Property: "RotationSpaceForLimitOnly", "bool", "",0
195
Property: "AxisLen", "double", "",10
196
Property: "PreRotation", "Vector3D", "",0,0,0
197
Property: "PostRotation", "Vector3D", "",0,0,0
198
Property: "RotationActive", "bool", "",0
199
Property: "RotationMin", "Vector3D", "",0,0,0
200
Property: "RotationMax", "Vector3D", "",0,0,0
201
Property: "RotationMinX", "bool", "",0
202
Property: "RotationMinY", "bool", "",0
203
Property: "RotationMinZ", "bool", "",0
204
Property: "RotationMaxX", "bool", "",0
205
Property: "RotationMaxY", "bool", "",0
206
Property: "RotationMaxZ", "bool", "",0
207
Property: "RotationStiffnessX", "double", "",0
208
Property: "RotationStiffnessY", "double", "",0
209
Property: "RotationStiffnessZ", "double", "",0
210
Property: "MinDampRangeX", "double", "",0
211
Property: "MinDampRangeY", "double", "",0
212
Property: "MinDampRangeZ", "double", "",0
213
Property: "MaxDampRangeX", "double", "",0
214
Property: "MaxDampRangeY", "double", "",0
215
Property: "MaxDampRangeZ", "double", "",0
216
Property: "MinDampStrengthX", "double", "",0
217
Property: "MinDampStrengthY", "double", "",0
218
Property: "MinDampStrengthZ", "double", "",0
219
Property: "MaxDampStrengthX", "double", "",0
220
Property: "MaxDampStrengthY", "double", "",0
221
Property: "MaxDampStrengthZ", "double", "",0
222
Property: "PreferedAngleX", "double", "",0
223
Property: "PreferedAngleY", "double", "",0
224
Property: "PreferedAngleZ", "double", "",0
225
Property: "InheritType", "enum", "",0
226
Property: "ScalingActive", "bool", "",0
227
Property: "ScalingMin", "Vector3D", "",1,1,1
228
Property: "ScalingMax", "Vector3D", "",1,1,1
229
Property: "ScalingMinX", "bool", "",0
230
Property: "ScalingMinY", "bool", "",0
231
Property: "ScalingMinZ", "bool", "",0
232
Property: "ScalingMaxX", "bool", "",0
233
Property: "ScalingMaxY", "bool", "",0
234
Property: "ScalingMaxZ", "bool", "",0
235
Property: "GeometricTranslation", "Vector3D", "",0,0,0
236
Property: "GeometricRotation", "Vector3D", "",0,0,0
237
Property: "GeometricScaling", "Vector3D", "",1,1,1
238
Property: "LookAtProperty", "object", ""
239
Property: "UpVectorProperty", "object", ""
240
Property: "Show", "bool", "",1
241
Property: "NegativePercentShapeSupport", "bool", "",1
242
Property: "DefaultAttributeIndex", "int", "",0''')
244
# Only mesh objects have color
245
file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
246
file.write('\n\t\t\tProperty: "Size", "double", "",100')
247
file.write('\n\t\t\tProperty: "Look", "enum", "",1')
249
return loc, rot, scale, matrix, matrix_rot
251
def write_camera_switch():
253
Model: "Model::Camera Switcher", "CameraSwitcher" {
258
Property: "Color", "Color", "A",0.8,0.8,0.8
259
Property: "Camera Index", "Integer", "A+",100
265
Culling: "CullingOff"
267
Name: "Model::Camera Switcher"
273
def write_camera_dummy(name, loc, near, far, proj_type, up):
274
file.write('\n\tModel: "Model::%s", "Camera" {' % name )
275
file.write('\n\t\tVersion: 232')
276
write_object_props(None, loc)
278
file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
279
file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0')
280
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",40')
281
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
282
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
283
file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",0')
284
file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",0')
285
file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0.63,0.63,0.63')
286
file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0')
287
file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1')
288
file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1')
289
file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0')
290
file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1')
291
file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0')
292
file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2')
293
file.write('\n\t\t\tProperty: "GateFit", "enum", "",0')
294
file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",21.3544940948486')
295
file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0')
296
file.write('\n\t\t\tProperty: "AspectW", "double", "",320')
297
file.write('\n\t\t\tProperty: "AspectH", "double", "",200')
298
file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",1')
299
file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0')
300
file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3')
301
file.write('\n\t\t\tProperty: "ShowName", "bool", "",1')
302
file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1')
303
file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0')
304
file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1')
305
file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0')
306
file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % near)
307
file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % far)
308
file.write('\n\t\t\tProperty: "FilmWidth", "double", "",0.816')
309
file.write('\n\t\t\tProperty: "FilmHeight", "double", "",0.612')
310
file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",1.33333333333333')
311
file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1')
312
file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",4')
313
file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1')
314
file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0')
315
file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2')
316
file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100')
317
file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0')
318
file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1')
319
file.write('\n\t\t\tProperty: "LockMode", "bool", "",0')
320
file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0')
321
file.write('\n\t\t\tProperty: "FitImage", "bool", "",0')
322
file.write('\n\t\t\tProperty: "Crop", "bool", "",0')
323
file.write('\n\t\t\tProperty: "Center", "bool", "",1')
324
file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1')
325
file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0')
326
file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5')
327
file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1')
328
file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0')
329
file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1')
330
file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",1.33333333333333')
331
file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0')
332
file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100')
333
file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50')
334
file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50')
335
file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",%i' % proj_type)
336
file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0')
337
file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0')
338
file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0')
339
file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5')
340
file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200')
341
file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0')
342
file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777')
343
file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0')
344
file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7')
345
file.write('\n\t\t}')
346
file.write('\n\t\tMultiLayer: 0')
347
file.write('\n\t\tMultiTake: 0')
348
file.write('\n\t\tHidden: "True"')
349
file.write('\n\t\tShading: Y')
350
file.write('\n\t\tCulling: "CullingOff"')
351
file.write('\n\t\tTypeFlags: "Camera"')
352
file.write('\n\t\tGeometryVersion: 124')
353
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
354
file.write('\n\t\tUp: %i,%i,%i' % up)
355
file.write('\n\t\tLookAt: 0,0,0')
356
file.write('\n\t\tShowInfoOnMoving: 1')
357
file.write('\n\t\tShowAudio: 0')
358
file.write('\n\t\tAudioColor: 0,1,0')
359
file.write('\n\t\tCameraOrthoZoom: 1')
362
def write_camera_default():
363
# This sucks but to match FBX converter its easier to
364
# write the cameras though they are not needed.
365
write_camera_dummy('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0))
366
write_camera_dummy('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1))
367
write_camera_dummy('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1))
368
write_camera_dummy('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0))
369
write_camera_dummy('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0))
370
write_camera_dummy('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0))
371
write_camera_dummy('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0))
373
def write_camera(ob, name):
375
Write a blender camera
379
height = render.sizeY
380
aspect = float(width)/height
384
file.write('\n\tModel: "Model::%s", "Camera" {' % name )
385
file.write('\n\t\tVersion: 232')
386
loc, rot, scale, matrix, matrix_rot = write_object_props(ob)
388
file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0')
389
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle)
390
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
391
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
392
file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
393
file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units?
394
file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto
395
file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0')
396
file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0')
397
file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1')
398
file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1')
399
file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0')
400
file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1')
401
file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0')
402
file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2')
403
file.write('\n\t\t\tProperty: "GateFit", "enum", "",0')
404
file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0')
405
file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width)
406
file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height)
408
'''Camera aspect ratio modes.
409
0 If the ratio mode is eWINDOW_SIZE, both width and height values aren't relevant.
410
1 If the ratio mode is eFIXED_RATIO, the height value is set to 1.0 and the width value is relative to the height value.
411
2 If the ratio mode is eFIXED_RESOLUTION, both width and height values are in pixels.
412
3 If the ratio mode is eFIXED_WIDTH, the width value is in pixels and the height value is relative to the width value.
413
4 If the ratio mode is eFIXED_HEIGHT, the height value is in pixels and the width value is relative to the height value.
415
Definition at line 234 of file kfbxcamera.h. '''
417
file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",2')
419
file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0')
420
file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3')
421
file.write('\n\t\t\tProperty: "ShowName", "bool", "",1')
422
file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1')
423
file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0')
424
file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1')
425
file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0')
426
file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart)
427
file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart)
428
file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0')
429
file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0')
430
file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect)
431
file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1')
432
file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",0')
433
file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1')
434
file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0')
435
file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2')
436
file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100')
437
file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0')
438
file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1')
439
file.write('\n\t\t\tProperty: "LockMode", "bool", "",0')
440
file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0')
441
file.write('\n\t\t\tProperty: "FitImage", "bool", "",0')
442
file.write('\n\t\t\tProperty: "Crop", "bool", "",0')
443
file.write('\n\t\t\tProperty: "Center", "bool", "",1')
444
file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1')
445
file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0')
446
file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5')
447
file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1')
448
file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0')
449
file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1')
450
file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",%.6f' % aspect)
451
file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0')
452
file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100')
453
file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50')
454
file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50')
455
file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",0')
456
file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0')
457
file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0')
458
file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0')
459
file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5')
460
file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200')
461
file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0')
462
file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777')
463
file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0')
464
file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7')
466
file.write('\n\t\t}')
467
file.write('\n\t\tMultiLayer: 0')
468
file.write('\n\t\tMultiTake: 0')
469
file.write('\n\t\tShading: Y')
470
file.write('\n\t\tCulling: "CullingOff"')
471
file.write('\n\t\tTypeFlags: "Camera"')
472
file.write('\n\t\tGeometryVersion: 124')
473
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
474
file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,1,0) * matrix_rot) )
475
file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,0,-1)*matrix_rot) )
477
#file.write('\n\t\tUp: 0,0,0' )
478
#file.write('\n\t\tLookAt: 0,0,0' )
480
file.write('\n\t\tShowInfoOnMoving: 1')
481
file.write('\n\t\tShowAudio: 0')
482
file.write('\n\t\tAudioColor: 0,1,0')
483
file.write('\n\t\tCameraOrthoZoom: 1')
486
def write_light(ob, name):
488
file.write('\n\tModel: "Model::%s", "Light" {' % name)
489
file.write('\n\t\tVersion: 232')
491
write_object_props(ob)
493
# Why are these values here twice?????? - oh well, follow the holy sdk's output
495
# Blender light types match FBX's, funny coincidence, we just need to
496
# be sure that all unsupported types are made into a point light
500
light_type = light.type
501
if light_type > 3: light_type = 0
503
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
504
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
505
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
506
file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
507
file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
508
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
509
file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1')
510
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (light.energy*100))
511
file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
512
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
513
file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col))
514
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (light.energy*100))
515
file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
516
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
517
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
518
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
519
file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
520
file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
521
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
522
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
523
file.write('\n\t\t\tProperty: "DecayType", "enum", "",0')
524
file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist)
525
file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0')
526
file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0')
527
file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0')
528
file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0')
529
file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0')
530
file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0')
531
file.write('\n\t\t\tProperty: "CastShadows", "bool", "",0')
532
file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1')
533
file.write('\n\t\t}')
534
file.write('\n\t\tMultiLayer: 0')
535
file.write('\n\t\tMultiTake: 0')
536
file.write('\n\t\tShading: Y')
537
file.write('\n\t\tCulling: "CullingOff"')
538
file.write('\n\t\tTypeFlags: "Light"')
539
file.write('\n\t\tGeometryVersion: 124')
544
world_amb = world.getAmb()
546
world_amb = (0,0,0) # Default value
549
def write_material(matname, mat):
550
file.write('\n\tMaterial: "Material::%s", "" {' % matname)
552
# Todo, add more material Properties.
554
mat_cold = tuple(mat.rgbCol)
555
mat_cols = tuple(mat.specCol)
556
#mat_colm = tuple(mat.mirCol) # we wont use the mirror color
557
mat_colamb = tuple([c for c in world_amb])
561
mat_hard = (float(mat.hard)-1)/5.10
562
mat_spec = mat.spec/2.0
563
mat_alpha = mat.alpha
564
mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS
566
mat_shader = 'Lambert'
568
if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT:
569
mat_shader = 'Lambert'
573
mat_cols = mat_cold = 0.8, 0.8, 0.8
574
mat_colamb = 0.0,0.0,0.0
581
mat_shadeless = False
584
file.write('\n\t\tVersion: 102')
585
file.write('\n\t\tShadingModel: "%s"' % mat_shader.lower())
586
file.write('\n\t\tMultiLayer: 0')
588
file.write('\n\t\tProperties60: {')
589
file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader)
590
file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0')
591
file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",0,0,0')
592
file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",1')
594
file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb)
595
file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.1f' % mat_amb)
596
file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold)
597
file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.1f' % mat_dif)
598
file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0')
599
file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1')
600
file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",0')
601
if not mat_shadeless:
602
file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols)
603
file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.1f' % mat_spec)
604
file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0')
605
file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0')
606
file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1')
607
file.write('\n\t\t\tProperty: "Emissive", "Vector3D", "",0,0,0')
608
file.write('\n\t\t\tProperty: "Ambient", "Vector3D", "",%.1f,%.1f,%.1f' % mat_colamb)
609
file.write('\n\t\t\tProperty: "Diffuse", "Vector3D", "",%.1f,%.1f,%.1f' % mat_cold)
610
if not mat_shadeless:
611
file.write('\n\t\t\tProperty: "Specular", "Vector3D", "",%.1f,%.1f,%.1f' % mat_cols)
612
file.write('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard)
613
file.write('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha)
614
if not mat_shadeless:
615
file.write('\n\t\t\tProperty: "Reflectivity", "double", "",0')
617
file.write('\n\t\t}')
620
def write_video(texname, tex):
621
# Same as texture really!
622
file.write('\n\tVideo: "Video::%s", "Clip" {' % texname)
627
Property: "FrameRate", "double", "",0
628
Property: "LastFrame", "int", "",0
629
Property: "Width", "int", "",0
630
Property: "Height", "int", "",0''')
633
fname_strip = strip_path(fname)
635
fname = fname_strip = ''
637
file.write('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip)
641
Property: "StartFrame", "int", "",0
642
Property: "StopFrame", "int", "",0
643
Property: "PlaySpeed", "double", "",1
644
Property: "Offset", "KTime", "",0
645
Property: "InterlaceMode", "enum", "",0
646
Property: "FreeRunning", "bool", "",0
647
Property: "Loop", "bool", "",0
648
Property: "AccessMode", "enum", "",0
652
file.write('\n\t\tFilename: "%s"' % fname_strip)
653
if fname_strip: fname_strip = '/' + fname_strip
654
file.write('\n\t\tRelativeFilename: "fbx%s"' % fname_strip) # make relative
658
def write_texture(texname, tex, num):
659
# if tex == None then this is a dummy tex
660
file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname)
661
file.write('\n\t\tType: "TextureVideoClip"')
662
file.write('\n\t\tVersion: 202')
663
# TODO, rare case _empty_ exists as a name.
664
file.write('\n\t\tTextureName: "Texture::%s"' % texname)
668
Property: "Translation", "Vector", "A+",0,0,0
669
Property: "Rotation", "Vector", "A+",0,0,0
670
Property: "Scaling", "Vector", "A+",1,1,1''')
671
file.write('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num)
673
Property: "TextureTypeUse", "enum", "",0
674
Property: "CurrentTextureBlendMode", "enum", "",1
675
Property: "UseMaterial", "bool", "",0
676
Property: "UseMipMap", "bool", "",0
677
Property: "CurrentMappingType", "enum", "",0
678
Property: "UVSwap", "bool", "",0
679
Property: "WrapModeU", "enum", "",0
680
Property: "WrapModeV", "enum", "",0
681
Property: "TextureRotationPivot", "Vector3D", "",0,0,0
682
Property: "TextureScalingPivot", "Vector3D", "",0,0,0
683
Property: "VideoProperty", "object", ""
686
file.write('\n\t\tMedia: "Video::%s"' % texname)
689
file.write('\n\t\tFileName: "%s"' % strip_path(fname))
690
file.write('\n\t\tRelativeFilename: "fbx/%s"' % strip_path(fname)) # need some make relative command
692
file.write('\n\t\tFileName: ""')
693
file.write('\n\t\tRelativeFilename: "fbx"')
696
ModelUVTranslation: 0,0
698
Texture_Alpha_Source: "None"
707
armatures = [] # We should export standalone armatures also
708
armatures_totbones = 0 # we need this because each bone is a model
709
for ob_base in sce.objects.context:
710
for ob, mtx in BPyObject.getDerivedObjects(ob_base):
711
#for ob in [ob_base,]:
713
if ob_type == 'Camera':
714
ob_cameras.append((sane_obname(ob), ob))
715
elif ob_type == 'Lamp':
716
ob_lights.append((sane_obname(ob), ob))
719
if ob_type == 'Mesh': me = ob.getData(mesh=1)
720
else: me = BPyMesh.getMeshFromObject(ob)
725
# 2.44 use mat.lib too for uniqueness
726
if mat: materials[mat.name] = mat
729
uvlayer_orig = me.activeUVLayer
730
for uvlayer in me.getUVLayerNames():
731
me.activeUVLayer = uvlayer
734
if img: textures[img.name] = img
736
me.activeUVLayer = uvlayer_orig
738
arm = BPyObject.getObjectArmature(ob)
741
armname = sane_obname(arm)
742
bones = arm.bones.values()
743
armatures_totbones += len(bones)
744
armatures.append((arm, armname, bones))
748
#### me.transform(ob.matrixWorld) # Export real ob coords.
749
#### High Quality, not realy needed for now.
750
#BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
751
ob_meshes.append( (sane_obname(ob), ob, mtx, me, mats, arm, armname) )
755
materials = [(sane_matname(mat), mat) for mat in materials.itervalues()]
756
textures = [(sane_texname(img), img) for img in textures.itervalues()]
757
materials.sort() # sort by name
761
materials = [('null', None)]
763
material_mapping = {} # blen name : index
765
texture_mapping_local = {None:0} # ditto
767
for texname, tex in textures:
768
texture_mapping_local[tex.name] = i
770
textures.insert(0, ('_empty_', None))
773
for matname, mat in materials:
774
if mat: mat = mat.name
775
material_mapping[mat] = i
782
;------------------------------------------------------------------
794
(len(textures)*2))) # add 1 for the root model 1 for global settings
797
ObjectType: "Model" {
805
armatures_totbones)) # add 1 for the root model
808
ObjectType: "Geometry" {
810
}''' % len(ob_meshes))
814
ObjectType: "Material" {
816
}''' % len(materials))
820
ObjectType: "Texture" {
822
}''' % len(textures)) # add 1 for an empty tex
824
ObjectType: "Video" {
826
}''' % len(textures)) # add 1 for an empty tex
829
ObjectType: "GlobalSettings" {
838
;------------------------------------------------------------------
842
# To comply with other FBX FILES
843
write_camera_switch()
845
# Write the null object
847
Model: "Model::blend_root", "Null" {
856
Culling: "CullingOff"
860
for obname, ob in ob_cameras:
861
write_camera(ob, obname)
863
for obname, ob in ob_lights:
864
write_light(ob, obname)
866
for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
867
file.write('\n\tModel: "Model::%s", "Mesh" {' % sane_obname(ob))
868
file.write('\n\t\tVersion: 232') # newline is added in write_object_props
869
write_object_props(ob, None, mtx)
870
file.write('\n\t\t}')
871
file.write('\n\t\tMultiLayer: 0')
872
file.write('\n\t\tMultiTake: 1')
873
file.write('\n\t\tShading: Y')
874
file.write('\n\t\tCulling: "CullingOff"')
876
# Write the Real Mesh data here
877
file.write('\n\t\tVertices: ')
881
file.write('%.6f,%.6f,%.6f' % tuple(v.co))
887
file.write(',%.6f,%.6f,%.6f'% tuple(v.co))
889
file.write('\n\t\tPolygonVertexIndex: ')
892
fi = [v.index for v in f]
893
# flip the last index, odd but it looks like
894
# this is how fbx tells one face from another
898
if len(f) == 3: file.write('%i,%i,%i' % fi )
899
else: file.write('%i,%i,%i,%i' % fi )
905
if len(f) == 3: file.write(',%i,%i,%i' % fi )
906
else: file.write(',%i,%i,%i,%i' % fi )
909
ed_val = [None, None]
910
LOOSE = Blender.Mesh.EdgeFlags.LOOSE
913
ed_val[0] = ed.v1.index
914
ed_val[1] = -(ed.v2.index+1)
916
file.write('%i,%i' % tuple(ed_val) )
922
file.write(',%i,%i' % tuple(ed_val) )
926
file.write('\n\t\tGeometryVersion: 124')
929
LayerElementNormal: 0 {
932
MappingInformationType: "ByVertice"
933
ReferenceInformationType: "Direct"
939
file.write('%.15f,%.15f,%.15f' % tuple(v.no))
945
file.write(',%.15f,%.15f,%.15f' % tuple(v.no))
947
file.write('\n\t\t}')
950
# Write VertexColor Layers
953
collayers = me.getColorLayerNames()
954
collayer_orig = me.activeColorLayer
955
for colindex, collayer in enumerate(collayers):
956
me.activeColorLayer = collayer
957
file.write('\n\t\tLayerElementColor: %i {' % colindex)
958
file.write('\n\t\t\tVersion: 101')
959
file.write('\n\t\t\tName: "%s"' % collayer)
962
MappingInformationType: "ByPolygonVertex"
963
ReferenceInformationType: "IndexToDirect"
967
ii = 0 # Count how many Colors we write
972
file.write('%i,%i,%i' % (col[0], col[1], col[2]))
976
file.write('\n\t\t\t\t')
978
file.write(',%i,%i,%i' % (col[0], col[1], col[2]))
980
ii+=1 # One more Color
982
file.write('\n\t\t\tColorIndex: ')
990
file.write('\n\t\t\t\t')
992
file.write(',%i' % j)
995
file.write('\n\t\t}')
999
# Write UV and texture layers.
1002
uvlayers = me.getUVLayerNames()
1003
uvlayer_orig = me.activeUVLayer
1004
for uvindex, uvlayer in enumerate(uvlayers):
1005
me.activeUVLayer = uvlayer
1006
file.write('\n\t\tLayerElementUV: %i {' % uvindex)
1007
file.write('\n\t\t\tVersion: 101')
1008
file.write('\n\t\t\tName: "%s"' % uvlayer)
1011
MappingInformationType: "ByPolygonVertex"
1012
ReferenceInformationType: "IndexToDirect"
1016
ii = 0 # Count how many UVs we write
1021
file.write('%.6f,%.6f' % tuple(uv))
1027
file.write(',%.6f,%.6f' % tuple(uv))
1031
file.write('\n\t\t\tUVIndex: ')
1033
for j in xrange(ii):
1035
file.write('%i' % j)
1039
file.write('\n\t\t\t\t')
1041
file.write(',%i' % j)
1044
file.write('\n\t\t}')
1047
file.write('\n\t\tLayerElementTexture: %i {' % uvindex)
1048
file.write('\n\t\t\tVersion: 101')
1049
file.write('\n\t\t\tName: "%s"' % uvlayer)
1052
MappingInformationType: "ByPolygon"
1053
ReferenceInformationType: "IndexToDirect"
1054
BlendMode: "Translucent"
1060
if img_key: img_key = img_key.name
1064
file.write( '%s' % texture_mapping_local[img_key])
1070
file.write(',%s' % texture_mapping_local[img_key])
1074
LayerElementTexture: 0 {
1077
MappingInformationType: "NoMappingInformation"
1078
ReferenceInformationType: "IndexToDirect"
1079
BlendMode: "Translucent"
1082
file.write('\n\t\t}')
1084
me.activeUVLayer = uvlayer_orig
1086
# Done with UV/textures.
1090
LayerElementMaterial: 0 {
1093
MappingInformationType: "ByPolygon"
1094
ReferenceInformationType: "IndexToDirect"
1097
# Build a material mapping for this
1098
material_mapping_local = {} # local-index : global index.
1099
for i, mat in enumerate(mats):
1101
material_mapping_local[i] = material_mapping[mat.name]
1103
material_mapping_local[i] = 0 # None material is zero for now.
1105
if not material_mapping_local:
1106
material_mapping_local[0] = 0
1108
len_material_mapping_local = len(material_mapping_local)
1113
if f_mat >= len_material_mapping_local:
1118
file.write( '%s' % material_mapping_local[f_mat])
1121
file.write('\n\t\t\t\t')
1124
file.write(',%s' % material_mapping_local[f_mat])
1127
file.write('\n\t\t}')
1133
Type: "LayerElementNormal"
1140
Type: "LayerElementMaterial"
1148
Type: "LayerElementTexture"
1155
Type: "LayerElementColor"
1162
Type: "LayerElementUV"
1167
file.write('\n\t\t}')
1169
if len(uvlayers) > 1:
1170
for i in xrange(1, len(uvlayers)):
1172
file.write('\n\t\tLayer: %i {' % i)
1173
file.write('\n\t\t\tVersion: 100')
1177
Type: "LayerElementUV"''')
1179
file.write('\n\t\t\t\tTypedIndex: %i' % i)
1180
file.write('\n\t\t\t}')
1186
Type: "LayerElementTexture"''')
1188
file.write('\n\t\t\t\tTypedIndex: %i' % i)
1189
file.write('\n\t\t\t}')
1191
file.write('\n\t\t}')
1193
if len(collayers) > 1:
1194
# Take into account any UV layers
1196
if uvlayers: layer_offset = len(uvlayers)-1
1198
for i in xrange(layer_offset, len(collayers)+layer_offset):
1199
file.write('\n\t\tLayer: %i {' % i)
1200
file.write('\n\t\t\tVersion: 100')
1204
Type: "LayerElementColor"''')
1206
file.write('\n\t\t\t\tTypedIndex: %i' % i)
1207
file.write('\n\t\t\t}')
1208
file.write('\n\t\t}')
1211
write_camera_default()
1213
for matname, mat in materials:
1214
write_material(matname, mat)
1216
# each texture uses a video, odd
1217
for texname, tex in textures:
1218
write_video(texname, tex)
1220
for texname, tex in textures:
1221
write_texture(texname, tex, i)
1224
# Finish Writing Objects
1225
# Write global settings
1230
Property: "UpAxis", "int", "",1
1231
Property: "UpAxisSign", "int", "",1
1232
Property: "FrontAxis", "int", "",2
1233
Property: "FrontAxisSign", "int", "",1
1234
Property: "CoordAxis", "int", "",0
1235
Property: "CoordAxisSign", "int", "",1
1236
Property: "UnitScaleFactor", "double", "",1
1245
;------------------------------------------------------------------
1249
file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}')
1250
for obname, ob in ob_cameras:
1251
file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % obname)
1253
for obname, ob in ob_lights:
1254
file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % obname)
1256
for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
1257
file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % obname)
1260
Model: "Model::Producer Perspective", "Camera" {
1262
Model: "Model::Producer Top", "Camera" {
1264
Model: "Model::Producer Bottom", "Camera" {
1266
Model: "Model::Producer Front", "Camera" {
1268
Model: "Model::Producer Back", "Camera" {
1270
Model: "Model::Producer Right", "Camera" {
1272
Model: "Model::Producer Left", "Camera" {
1274
Model: "Model::Camera Switcher", "CameraSwitcher" {
1277
for matname, mat in materials:
1278
file.write('\n\tMaterial: "Material::%s", "" {\n\t}' % matname)
1281
for texname, tex in textures:
1282
file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {\n\t}' % texname)
1283
for texname, tex in textures:
1284
file.write('\n\tVideo: "Video::%s", "Clip" {\n\t}' % texname)
1289
; Object connections
1290
;------------------------------------------------------------------
1294
# write the fake root node
1295
file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"')
1297
for obname, ob in ob_cameras:
1298
file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
1300
for obname, ob in ob_lights:
1301
file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
1303
for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
1304
file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
1306
for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
1307
# Connect all materials to all objects, not good form but ok for now.
1309
file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_matname(mat), obname))
1312
for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
1313
for texname, tex in textures:
1314
file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (texname, obname))
1316
for texname, tex in textures:
1317
file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname))
1322
# Clear mesh data Only when writing with modifiers applied
1323
#for obname, ob, me, mats, arm, armname in objects:
1327
def write_footer(file, sce, world):
1332
has_mist = world.mode & 1
1334
mist_intense, mist_start, mist_end, mist_height = world.mist
1338
file.write('\n;Takes and animation section')
1339
file.write('\n;----------------------------------------------------')
1341
file.write('\nTakes: {')
1342
file.write('\n\tCurrent: ""')
1344
file.write('\n;Version 5 settings')
1345
file.write('\n;------------------------------------------------------------------')
1347
file.write('\nVersion5: {')
1348
file.write('\n\tAmbientRenderSettings: {')
1349
file.write('\n\t\tVersion: 101')
1350
file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world.amb))
1352
file.write('\n\tFogOptions: {')
1353
file.write('\n\t\tFlogEnable: %i' % has_mist)
1354
file.write('\n\t\tFogMode: 0')
1355
file.write('\n\t\tFogDensity: %.3f' % mist_intense)
1356
file.write('\n\t\tFogStart: %.3f' % mist_start)
1357
file.write('\n\t\tFogEnd: %.3f' % mist_end)
1358
file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world.hor))
1360
file.write('\n\tSettings: {')
1361
file.write('\n\t\tFrameRate: "%i"' % render.fps)
1362
file.write('\n\t\tTimeFormat: 1')
1363
file.write('\n\t\tSnapOnFrames: 0')
1364
file.write('\n\t\tReferenceTimeIndex: -1')
1365
file.write('\n\t\tTimeLineStartTime: %i' % render.sFrame)
1366
file.write('\n\t\tTimeLineStopTime: %i' % render.eFrame)
1368
file.write('\n\tRendererSetting: {')
1369
file.write('\n\t\tDefaultCamera: "Producer Perspective"')
1370
file.write('\n\t\tDefaultViewingMode: 0')
1375
# Incase sombody imports this, clean up by clearing global dicts
1376
sane_name_mapping_ob.clear()
1377
sane_name_mapping_mat.clear()
1378
sane_name_mapping_tex.clear()
1382
def write_ui(filename):
1383
if not filename.lower().endswith('.fbx'):
1386
#if not BPyMessages.Warning_SaveOver(filename):
1388
sce = bpy.data.scenes.active
1391
Blender.Window.WaitCursor(1)
1392
file = open(filename, 'w')
1394
write_scene(file, sce, world)
1395
write_footer(file, sce, world)
1396
Blender.Window.WaitCursor(0)
1398
if __name__ == '__main__':
1399
Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx'))
1400
#write_ui('/test.fbx')