changed copyright years in source files
[fegdk.git] / tools / blender-exporter / feanm_export.py
blobae55a3e6ee1d691fbaaa118f516af263671a0ac0
1 #!BPY
3 ## $Header$
5 ##
6 ## fegdk: FE Game Development Kit
7 ## Copyright (C) 2001-2008 Alexey "waker" Yakovenko
8 ##
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
23 ## Alexey Yakovenko
24 ## waker@users.sourceforge.net
27 """ Registration info for Blender menus:
28 Name: 'FE animation (.anm)...'
29 Blender: 241
30 Group: 'Export'
31 Submenu: 'Export to FEGDK anm file format' export
32 Tip: 'Export to FEGDK anm file format'
33 """
35 __author__ = "Alexey (waker) Yakovenko"
36 __url__ = ("Author's site, http://fegdk.sourceforge.net")
37 __version__ = "1.0"
39 __bpydoc__ = """\
40 Animation exporter for FEGDK
41 http://fegdk.sf.net
42 """
45 # $Id$
47 import Blender
48 from Blender import Types, Object, NMesh, Material, Armature, Mathutils
49 from Blender.Mathutils import *
51 def event(evt, val):
52 if evt == Blender.Draw.ESCKEY and not val: Blender.Draw.Exit()
54 def bevent(evt):
56 if evt == 1: Blender.Draw.Exit()
60 #***********************************************
61 #***********************************************
62 # EXPORTER
63 #***********************************************
64 #***********************************************
66 class feExport:
68 def __init__ (self):
69 self.indent = 0
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 ()
88 for c in triples:
89 if (c.vec[1][0] >= self.anim_start) and (c.vec[1][0] <= self.anim_end):
90 h1, p, h2 = c.vec
91 name = "unknown"
92 mult = 1.0
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 ()
110 for c in triples:
111 t = int (c.vec[1][0])
112 if (t not in rotFrames) and (t >= self.anim_start) and (t <= self.anim_end):
113 rotFrames.append (t)
115 def writeRotationQuats (self, obj, rotFrames):
116 if len (rotFrames):
117 for t in rotFrames:
118 if t > 0:
119 Blender.Set('curframe',t)
120 mtx = obj.getMatrix ('worldspace')
121 par = obj.getParent ()
122 if par:
123 mtx = mtx * par.getInverseMatrix ()
124 quat = mtx.toQuat ()
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
140 numbones = 0
141 objs = Object.Get ()
142 for ob in objs:
143 ipo = ob.getIpo ()
144 if (ipo):
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
150 objs = Object.Get ()
151 for ob in objs:
152 ipo = ob.getIpo ()
153 if (ipo):
154 self.writeString ("ipo_quat_keyframes \"%s\" {" % ob.name)
155 rotFrames = []
156 for curve in ipo.getCurves ():
157 if curve:
158 self.exportIpoCurve (curve)
159 nm = curve.getName ()
160 if nm == "RotX" or nm == "RotY" or nm == "RotZ":
161 self.collectRotationKeyFrames (curve, rotFrames)
162 rotFrames.sort ()
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 ():
170 if curve:
171 self.exportIpoCurve (curve)
172 self.writeString ("}")
173 self.indent = self.indent - 1
174 self.writeString ("}")
175 self.file.close ()
176 Blender.Set('curframe',curframe)
179 #***********************************************
180 # MAIN
181 #***********************************************
183 def my_callback(filename):
184 fname=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)