6 ## fegdk: FE Game Development Kit
7 ## Copyright (C) 2001-2008 Alexey "waker" Yakovenko
9 ## This library is free software; you can redistribute it and/or
10 ## modify it under the terms of the GNU Library General Public
11 ## License as published by the Free Software Foundation; either
12 ## version 2 of the License, or (at your option) any later version.
14 ## This library is distributed in the hope that it will be useful,
15 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ## Library General Public License for more details.
19 ## You should have received a copy of the GNU Library General Public
20 ## License along with this library; if not, write to the Free
21 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ## waker@users.sourceforge.net
27 """ Registration info for Blender menus:
28 Name: 'FE animation (.anm)...'
31 Submenu: 'Export to FEGDK anm file format' export
32 Tip: 'Export to FEGDK anm file format'
35 __author__
= "Alexey (waker) Yakovenko"
36 __url__
= ("Author's site, http://fegdk.sourceforge.net")
40 Animation exporter for FEGDK
48 from Blender
import Types
, Object
, NMesh
, Material
, Armature
, Mathutils
49 from Blender
.Mathutils
import *
52 if evt
== Blender
.Draw
.ESCKEY
and not val
: Blender
.Draw
.Exit()
56 if evt
== 1: Blender
.Draw
.Exit()
60 #***********************************************
61 #***********************************************
63 #***********************************************
64 #***********************************************
72 #------------------------------------------------
73 # we don't do it like we did w/ 3dsmax plugin, just write on the fly
75 def writeString (self
, s
):
76 for i
in range (0, self
.indent
):
77 self
.file.write ("\t")
78 self
.file.write ("%s\n" % s
)
80 def writeMatrix (self
, m
):
81 self
.writeString ("\t\t%s %s %s" % (m
[0][0], m
[0][1], m
[0][2]))
82 self
.writeString ("\t\t%s %s %s" % (m
[1][0], m
[1][1], m
[1][2]))
83 self
.writeString ("\t\t%s %s %s" % (m
[2][0], m
[2][1], m
[2][2]))
84 self
.writeString ("\t\t%s %s %s" % (m
[3][0], m
[3][1], m
[3][2]))
86 def exportIpoCurve (self
, curve
):
87 triples
= curve
.getPoints ()
89 if (c
.vec
[1][0] >= self
.anim_start
) and (c
.vec
[1][0] <= self
.anim_end
):
93 if curve
.getName () == "LocX": name
= "x"
94 if curve
.getName () == "LocY": name
= "y"
95 if curve
.getName () == "LocZ": name
= "z"
96 # if curve.getName () == "RotX": name = "rx"
97 # if curve.getName () == "RotY": name = "ry"
98 # if curve.getName () == "RotZ": name = "rz"
99 if curve
.getName () == "SizeX": name
= "sx"
100 if curve
.getName () == "SizeY": name
= "sy"
101 if curve
.getName () == "SizeZ": name
= "sz"
103 # write out scale and position as ipo curves;
104 if name
!= "unknown":
105 self
.writeString ("\t%s { %f %f %f %f %f %f }" % (name
, (h1
[0]-1)/25.0, h1
[1]*mult
, (p
[0]-1)/25.0, p
[1]*mult
, (h2
[0]-1)/25.0, h2
[1]*mult
))
108 def collectRotationKeyFrames (self
, curve
, rotFrames
):
109 triples
= curve
.getPoints ()
111 t
= int (c
.vec
[1][0])
112 if (t
not in rotFrames
) and (t
>= self
.anim_start
) and (t
<= self
.anim_end
):
115 def writeRotationQuats (self
, obj
, rotFrames
):
119 Blender
.Set('curframe',t
)
120 mtx
= obj
.getMatrix ('worldspace')
121 par
= obj
.getParent ()
123 mtx
= mtx
* par
.getInverseMatrix ()
125 self
.writeString ("\trot { %f %f %f %f %f }" % ((t
-1) / float (self
.anim_fps
), quat
.w
, quat
.x
, quat
.y
, quat
.z
))
127 def exportAnimation (self
, filename
):
128 curframe
= Blender
.Get('curframe')
129 self
.file = open (filename
, "w")
130 self
.writeString ("animation \"%s\" {" % self
.sceneName
)
132 self
.anim_start
= Blender
.Get ('staframe')
133 self
.anim_end
= Blender
.Get ('endframe')
135 scn
= Blender
.Scene
.GetCurrent ()
136 rc
= scn
.getRenderingContext ()
137 self
.anim_fps
= rc
.framesPerSec ()
139 # calc number of animated bones
145 numbones
= numbones
+ 1
147 self
.writeString ("\tduration %f\n" % ((self
.anim_end
- self
.anim_start
- 1) / float (self
.anim_fps
)))
148 self
.writeString ("\tnumbones %d\n" % (numbones
))
149 self
.indent
= self
.indent
+ 1
154 self
.writeString ("ipo_quat_keyframes \"%s\" {" % ob
.name
)
156 for curve
in ipo
.getCurves ():
158 self
.exportIpoCurve (curve
)
159 nm
= curve
.getName ()
160 if nm
== "RotX" or nm
== "RotY" or nm
== "RotZ":
161 self
.collectRotationKeyFrames (curve
, rotFrames
)
163 self
.writeRotationQuats (ob
, rotFrames
)
164 self
.writeString ("}")
165 actions
= Armature
.NLA
.GetActions ()
166 for a
in actions
.values ():
167 for bone
, ipo
in a
.getAllChannelIpos().iteritems ():
168 self
.writeString ("ipo_quat_keyframes \"%s\" {" % bone
)
169 for curve
in ipo
.getCurves ():
171 self
.exportIpoCurve (curve
)
172 self
.writeString ("}")
173 self
.indent
= self
.indent
- 1
174 self
.writeString ("}")
176 Blender
.Set('curframe',curframe
)
179 #***********************************************
181 #***********************************************
183 def my_callback(filename
):
185 if fname
.find('.anm', -4) > 0: fname
= fname
[:-4]
186 fname_anm
= fname
+'.anm'
188 exporter
= feExport ()
189 exporter
.sceneName
= fname
190 exporter
.exportAnimation(fname_anm
)
191 print ("done exporting")
193 fname
= Blender
.sys
.makename(ext
= ".anm")
194 Blender
.Window
.FileSelector(my_callback
, "Export FE .anm", fname
)