comparison utils/frminfo/make_xml.py @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 #! /usr/bin/env python
2 import os,sys,string
3 SUFFIX_LIST = [ "aa","ab","at","ae","ak","al","an","ao","ap","ar","as","aq" ]
4 IDLE,WALK,RUN,CLIMB,PICKUP,USE,DODGE,HITFRONT,HITBACK,KICK,THROW,PUNCH = range(len(SUFFIX_LIST))
5 ACTION_IDS = range(len(SUFFIX_LIST))
6 ACTION_NAMES = [
7 "IDLE","WALK","RUN","CLIMB","PICKUP","USE","DODGE","HITFRONT","HITBACK","KICK","THROW","PUNCH"
8 ]
9 SUFFIX_DICT = dict(zip(SUFFIX_LIST,ACTION_IDS))
10
11 USAGE="""
12 *** make_xml.py ***
13 Generates XML Critter information from frm info in critter.dat
14 --list List all critters
15 --to-xml CRITTER Output XML generated for a critter CRITTER
16 into a file in the current directory
17 --all-xml DIRECTORY Output XML files for all critters in the list
18 into the directory DIRECTORY
19 """
20
21 CRITTER_XML = string.Template("""\
22 <!--
23 This is an auto-generated XML file
24 defining the animation actions a
25 critter can perform.
26
27 Generator: make_xml.py
28 -->
29 <complex-animation name="$name" geometry="1">
30 $actions
31 </complex-animation>""")
32
33 ACTION_XML = string.Template("""\
34 <!-- ACTION: $name FRAMES: $numFrames FPS: $fps -->
35 <action id="$id" direction="255">
36 <animation src="$filename"/>
37 $partialActions
38 </action>
39 """)
40
41 PARTIAL_ACTION_XML=string.Template("""\
42 <partial-action number="$number">
43 <frames start="$startFrame" number="$endFrame"/>
44 <step number="$stepNumber"/>
45 <partial-action action="$nextActionId" number="$nextNumber" direction="255"/>
46 </partial-action>
47 """)
48
49 MOTION_XML = string.Template("""\
50 <motion distance="$distance"/>
51 """)
52
53 class Action(object):
54 def __init__(self,critter,suffix):
55 self.critter = critter
56 self.suffix = suffix
57 self.id = SUFFIX_DICT[ suffix ]
58 self.filename = "art/critters/" + self.critter.basename + self.suffix +".frm"
59 self.frminfo_parsed = False
60
61 def __str__(self):
62 if self.frminfo_parsed:
63 return self.suffix + "[nframes="+str(self.numframes)+",fps="+str(self.fps)+"]"
64 return self.suffix + "[id="+str(self.id)+"]"
65
66 def parseFrmInfo(self):
67 if self.frminfo_parsed:
68 return
69 frminfo = os.popen("./frminfo -t " + self.filename).read()
70 print >> sys.stderr, "Parsing FRMINFO: ",self.filename
71 frminfo = [tuple(line.replace(" ","").split("=")) for line in frminfo.split("\n")[:-1]]
72 values = dict(frminfo)
73 self.numframes = int(values['num_frames'])
74 self.fps = int(values['frames_per_second'])
75 self.shiftx = int(values["shift_xy"].split(',')[0])
76 self.frminfo_parsed = True
77 def measureDistance(self):
78 cmd ="./frminfo -t " +self.filename + " -i " + str(self.numframes-1)+ " -d 1"
79 frminfo = os.popen(cmd).read()
80 frminfo = [tuple(line.replace(" ","").split("=")) for line in frminfo.split("\n")[:-1]]
81 values = dict(frminfo)
82 x,y = map(int,values["shift_xy"].split(","))
83 distance = (x - self.shiftx+ 16) / 32
84 print >> sys.stderr, ACTION_NAMES[self.id],"distance:",distance
85 return distance
86
87 def generatePartialActions(self,actionId):
88 partialActions = ""
89 npas=1
90 if actionId in [WALK,RUN]:
91 npas = self.measureDistance()
92 partialActions += MOTION_XML.substitute(distance=npas)
93
94 if npas==0:
95 npas=1
96
97 delta = (self.numframes/npas)
98 startFrame=0
99 endFrame = delta
100 nextActionId = actionId
101 for number in range(npas):
102 nextNumber = (number+1) % npas
103 stepNumber=number
104 partialActions += PARTIAL_ACTION_XML.safe_substitute(locals())
105 startFrame += delta
106 return partialActions
107
108 def buildXML(self):
109 #if self.id not in [RUN,WALK]: return ""
110 self.parseFrmInfo()
111 id = self.id
112 name = ACTION_NAMES[id]
113 fps = self.fps
114 numFrames = self.numframes
115 filename = self.filename
116 partialActions = self.generatePartialActions(id)
117 return ACTION_XML.safe_substitute(locals())
118
119 class Critter(object):
120 def __init__(self,basename):
121 self.basename = basename
122 self.actions = {}
123 self.xml=""
124 def __str__(self):
125 return self.basename +"("+",".join(map(str,self.actions.values()))+")"
126
127 def addAction(self,suffix):
128 action = Action(self,suffix)
129 self.actions[ action.id ] = action
130
131 def buildXML(self):
132 if self.xml: return self.xml
133 name = self.basename
134 actions = ""
135 for action in self.actions.values():
136 actions += action.buildXML()
137
138 return CRITTER_XML.safe_substitute(locals())
139
140 def readCritters():
141 critters = os.popen("./frminfo -l 14").read().split("\n")[1:]
142 critter_types = {}
143 for critter in critters:
144 basename = os.path.basename(critter).split('.')[0][:6]
145 if not basename:
146 continue
147
148 action = os.path.basename(critter).split('.')[0][6:]
149 if not critter_types.has_key(basename):
150 critter_types[ basename ] = Critter(basename)
151 critter = critter_types[ basename ]
152 critter.addAction( action )
153
154 return critter_types
155
156
157 def exportToXML(critter_name,critters,directory="./"):
158 if not critters.has_key(critter_name):
159 print >> sys.stderr, "Critter ",critter_name," not found."
160 sys.exit(1)
161
162 critter = critters[critter_name]
163
164 xml= critter.buildXML()
165 fname = os.path.join(directory,critter.basename + ".xml")
166 file =open(fname,"w")
167 file.write(xml)
168 print >> sys.stderr, "Wrote to ",fname
169
170 def main():
171 if len(sys.argv) == 1:
172 print USAGE
173 sys.exit(1)
174 print >> sys.stderr, "Reading Critter List"
175 critters = readCritters()
176 if sys.argv[1] == '--list':
177 for name,critter in critters.items():
178 name_getter = lambda x: ACTION_NAMES[x]
179 print name," actions = ",map(name_getter,critter.actions.keys())
180 sys.exit(0)
181
182 if len(sys.argv) == 2:
183 print USAGE
184 sys.exit(1)
185
186 if sys.argv[1] == '--to-xml':
187 exportToXML( sys.argv[2], critters)
188 if sys.argv[1]=='--all-xml':
189 for critter_name in critters.keys():
190 exportToXML(critter_name,critters,sys.argv[2])
191
192 if __name__=="__main__": main();