~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to release/scripts/bvh_import.py

  • Committer: Bazaar Package Importer
  • Author(s): Lukas Fittl
  • Date: 2006-09-20 01:57:27 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060920015727-gmoqlxwstx9wwqs3
Tags: 2.42a-1ubuntu1
* Merge from Debian unstable (Closes: Malone #55903). Remaining changes:
  - debian/genpot: Add python scripts from Lee June <blender@eyou.com> to
    generate a reasonable PO template from the sources. Since gettext is used
    in a highly nonstandard way, xgettext does not work for this job.
  - debian/rules: Call the scripts, generate po/blender.pot, and clean it up
    in the clean target.
  - Add a proper header to the generated PO template.
* debian/control: Build depend on libavformat-dev >= 3:0.cvs20060823-3.1,
  otherwise this package will FTBFS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!BPY
2
 
 
3
 
"""
4
 
Name: 'Motion Capture (.bvh)...'
5
 
Blender: 239
6
 
Group: 'Import'
7
 
Tip: 'Import a (.bvh) motion capture file'
8
 
"""
9
 
 
10
 
__author__ = "Campbell Barton"
11
 
__url__ = ("blender", "elysiun")
12
 
__version__ = "1.0.4 05/12/04"
13
 
 
14
 
__bpydoc__ = """\
15
 
This script imports BVH motion capture data to Blender.
16
 
 
17
 
Supported: Poser 3.01<br>
18
 
 
19
 
Missing:<br>
20
 
 
21
 
Known issues:<br>
22
 
 
23
 
Notes:<br>
24
 
         Jean-Michel Soler improved importer to support Poser 3.01 files;<br>
25
 
         Jean-Baptiste Perin wrote a script to create an armature out of the
26
 
Empties created by this importer, it's in the Scripts window -> Scripts -> Animation menu.
27
 
"""
28
 
 
29
 
# $Id: bvh_import.py,v 1.9 2006/01/12 21:30:00 letterrip Exp $
30
 
#
31
 
 
32
 
#===============================================#
33
 
# BVH Import script 1.05 patched by Campbell    #
34
 
# Modified to use Mathutils for matrix math,    #
35
 
# Fixed possible joint naming bug,              #
36
 
# Imports BVH's with bad EOF gracefully         #
37
 
# Fixed duplicate joint names, make them unique #
38
 
# Use \r as well as \n for newlines             #
39
 
# Added suppot for nodes with 0 motion channels #
40
 
# Rotation IPOs never cross more then 180d      #
41
 
#    fixes sub frame tweening and time scaling  #
42
 
# 5x overall speedup.                           #
43
 
# 06/12/2005,                                   #       
44
 
#===============================================#
45
 
 
46
 
#===============================================#
47
 
# BVH Import script 1.04 patched by jms         #
48
 
# Small modif for blender 2.40                  #
49
 
# 04/12/2005,                                   #       
50
 
#===============================================#
51
 
 
52
 
#===============================================#
53
 
# BVH Import script 1.03 patched by Campbell    #
54
 
# Small optimizations and scale input           #
55
 
# 01/01/2005,                                   #       
56
 
#===============================================#
57
 
 
58
 
#===============================================#
59
 
# BVH Import script 1.02 patched by Jm Soler    #
60
 
# to the Poser 3.01 bvh file                    #
61
 
# 28/12/2004,                                   #       
62
 
#===============================================#
63
 
 
64
 
#===============================================#
65
 
# BVH Import script 1.0 by Campbell Barton      #
66
 
# 25/03/2004, euler rotation code taken from    #
67
 
# Reevan Mckay's BVH import script v1.1         #
68
 
# if you have any questions about this scrip.   #
69
 
# email me cbarton@metavr.com                   #
70
 
#===============================================#
71
 
 
72
 
#===============================================#
73
 
# TODO:                                         #
74
 
# * Create bones when importing                 #
75
 
# * Make an IPO jitter removal script           #
76
 
# * Work out a better naming system             #
77
 
#===============================================#
78
 
 
79
 
# -------------------------------------------------------------------------- 
80
 
# BVH Import v1.05 by Campbell Barton (AKA Ideasman) 
81
 
# -------------------------------------------------------------------------- 
82
 
# ***** BEGIN GPL LICENSE BLOCK ***** 
83
 
84
 
# This program is free software; you can redistribute it and/or 
85
 
# modify it under the terms of the GNU General Public License 
86
 
# as published by the Free Software Foundation; either version 2 
87
 
# of the License, or (at your option) any later version. 
88
 
89
 
# This program is distributed in the hope that it will be useful, 
90
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
91
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
92
 
# GNU General Public License for more details. 
93
 
94
 
# You should have received a copy of the GNU General Public License 
95
 
# along with this program; if not, write to the Free Software Foundation, 
96
 
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
97
 
98
 
# ***** END GPL LICENCE BLOCK ***** 
99
 
# -------------------------------------------------------------------------- 
100
 
 
101
 
import Blender
102
 
from Blender import Window, Object, Scene, Ipo, Draw
103
 
from Blender.Scene import Render
104
 
 
105
 
 
106
 
# Attempt to load psyco, speed things up
107
 
try:
108
 
        import psyco
109
 
        psyco.full()    
110
 
        print 'using psyco to speed up BVH importing'
111
 
except:
112
 
        #print 'psyco is not present on this system'
113
 
        pass
114
 
 
115
 
 
116
 
 
117
 
def main():
118
 
        global scale
119
 
        scale = None
120
 
        
121
 
        # Update as we load?
122
 
        debug = 0
123
 
        
124
 
        def getScale():
125
 
                return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3)
126
 
        
127
 
        
128
 
        #===============================================#
129
 
        # MAIN FUNCTION - All things are done from here #
130
 
        #===============================================#
131
 
        def loadBVH(filename):
132
 
                global scale
133
 
                print '\nBVH Importer 1.05 by Campbell Barton (Ideasman) - cbarton@metavr.com'
134
 
                
135
 
                objectCurveMapping = {}
136
 
                objectNameMapping = {}
137
 
                objectMotiondataMapping = {}
138
 
                
139
 
                # Here we store the Ipo curves in the order they load.
140
 
                channelCurves = []
141
 
                
142
 
                # Object list
143
 
                # We need this so we can loop through the objects and edit there IPO's 
144
 
                # Chenging there rotation to EULER rotation
145
 
                objectList = []
146
 
                
147
 
                if scale == None:
148
 
                        tempscale = getScale()
149
 
                        if tempscale:
150
 
                                scale = tempscale
151
 
                        else:
152
 
                                scale = 0.01
153
 
                
154
 
                Window.WaitCursor(1)
155
 
                # Unique names, dont reuse any of these names.
156
 
                uniqueObNames = [ob.name for ob in Object.Get()]
157
 
                
158
 
                
159
 
                # FUNCTIONS ====================================#
160
 
                def getUniqueObName(name):
161
 
                        i = 0
162
 
                        newname = name[:min(len(name), 12)] # Concatinate to 12 chars
163
 
                        while newname in uniqueObNames:
164
 
                                newname = name + str(i)
165
 
                                i+=1
166
 
                        return newname
167
 
                        
168
 
                # Change the order rotation is applied.
169
 
                RotationMatrix = Blender.Mathutils.RotationMatrix
170
 
                MATRIX_IDENTITY_3x3 = Blender.Mathutils.Matrix([1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0])
171
 
                def eulerRotate(x,y,z): 
172
 
                        x,y,z = x%360,y%360,z%360 # Clamp all values between 0 and 360, values outside this raise an error.
173
 
                        xmat = RotationMatrix(x,3,'x')
174
 
                        ymat = RotationMatrix(y,3,'y')
175
 
                        zmat = RotationMatrix(z,3,'z')
176
 
                        # Standard BVH multiplication order, apply the rotation in the order Z,X,Y
177
 
                        return (ymat*(xmat * (zmat * MATRIX_IDENTITY_3x3))).toEuler()
178
 
                
179
 
 
180
 
                currentFrame = 1 # Set the initial frame to import all data to.
181
 
                
182
 
                #===============================================#
183
 
                # makeJoint: Here we use the node data          #
184
 
                # from the BVA file to create an empty          #
185
 
                #===============================================#
186
 
                BVH2BLEND_TX_NAME = {'Xposition':'LocX','Yposition':'LocY','Zposition':'LocZ','Xrotation':'RotX','Yrotation':'RotY','Zrotation':'RotZ'}
187
 
                def makeJoint(name, parent, offset, channels):
188
 
                        ob = Object.New('Empty', name) # New object, ob is shorter and nicer to use.
189
 
                        
190
 
                        objectNameMapping[name] = ob
191
 
                        scn.link(ob) # place the object in the current scene
192
 
                        ob.sel = 1
193
 
                        
194
 
                        # Make me a child of another empty.
195
 
                        # Vale of None will make the empty a root node (no parent)
196
 
                        if parent[-1]: # != None
197
 
                                obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here.
198
 
                                obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast.
199
 
                
200
 
                        # Offset Empty from BVH's initial joint location.
201
 
                        ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
202
 
                
203
 
                        # Add Ipo's for necessary channels
204
 
                        newIpo = Ipo.New('Object', name)
205
 
                        ob.setIpo(newIpo)
206
 
                        obname = ob.name
207
 
                        for channelType in channels:
208
 
                                channelType = BVH2BLEND_TX_NAME[channelType]
209
 
                                curve = newIpo.addCurve(channelType)
210
 
                                curve.setInterpolation('Linear')
211
 
                                objectCurveMapping[(obname, channelType)] = curve
212
 
                
213
 
                        # Add to object list
214
 
                        objectList.append(ob)
215
 
                        
216
 
                        # Redraw if debugging
217
 
                        if debug: Blender.Redraw()
218
 
                        
219
 
                        
220
 
                #===============================================#
221
 
                # makeEnd: Here we make an end node             #
222
 
                # This is needed when adding the last bone      #
223
 
                #===============================================#
224
 
                def makeEnd(parent, offset):
225
 
                        new_name = parent[-1] + '_end'
226
 
                        ob = Object.New('Empty', new_name) # New object, ob is shorter and nicer to use.
227
 
                        objectNameMapping[new_name] = ob
228
 
                        scn.link(ob)
229
 
                        ob.sel = 1
230
 
                        
231
 
                        # Dont check for a parent, an end node MUST have a parent
232
 
                        obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here.
233
 
                        obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast.
234
 
                
235
 
                        # Offset Empty
236
 
                        ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) 
237
 
                        
238
 
                        # Redraw if debugging
239
 
                        if debug: Blender.Redraw()
240
 
                # END FUNCTION DEFINITIONS ====================================#
241
 
                        
242
 
                
243
 
                
244
 
                
245
 
                time1 = Blender.sys.time()
246
 
                
247
 
                # Get the current scene.
248
 
                scn = Scene.GetCurrent()
249
 
                #context = scn.getRenderingContext()
250
 
                
251
 
                # DeSelect All
252
 
                for ob in scn.getChildren():
253
 
                        ob.sel = 0
254
 
                
255
 
                # File loading stuff
256
 
                # Open the file for importing
257
 
                file = open(filename, 'r')      
258
 
                
259
 
                # Seperate into a list of lists, each line a list of words.
260
 
                lines = file.readlines()
261
 
                # Non standard carrage returns?
262
 
                if len(lines) == 1:
263
 
                        lines = lines[0].split('\r')
264
 
                
265
 
                # Split by whitespace.
266
 
                lines =[ll for ll in [ [w for w in l.split() if w != '\n' ] for l in lines] if ll]
267
 
                # End file loading code
268
 
        
269
 
                
270
 
                
271
 
                # Create Hirachy as empties
272
 
                if lines[0][0] == 'HIERARCHY':
273
 
                        print 'Importing the BVH Hierarchy for:', filename
274
 
                else:
275
 
                        return 'ERROR: This is not a BVH file'
276
 
                
277
 
                # A liniar list of ancestors to keep track of a single objects heratage
278
 
                # at any one time, this is appended and removed, dosent store tree- just a liniar list.
279
 
                # ZERO is a place holder that means we are a root node. (no parents)
280
 
                parent = [None] 
281
 
                
282
 
                #channelList, sync with objectList:  [[channelType1, channelType2...],  [channelType1, channelType2...)]
283
 
                channelList = []
284
 
                channelIndex = -1
285
 
                
286
 
                lineIdx = 0 # An index for the file.
287
 
                while lineIdx < len(lines) -1:
288
 
                        #...
289
 
                        if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT':
290
 
                                
291
 
                                # Join spaces into 1 word with underscores joining it.
292
 
                                if len(lines[lineIdx]) > 2:
293
 
                                        lines[lineIdx][1] = '_'.join(lines[lineIdx][1:])
294
 
                                        lines[lineIdx] = lines[lineIdx][:2]
295
 
                                
296
 
                                # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
297
 
                                
298
 
                                # Make sure the names are unique- Object names will match joint names exactly and both will be unique.
299
 
                                name = getUniqueObName(lines[lineIdx][1])
300
 
                                uniqueObNames.append(name)
301
 
                                
302
 
                                print '%snode: %s, parent: %s' % (len(parent) * '  ', name,  parent[-1])
303
 
                                
304
 
                                lineIdx += 2 # Incriment to the next line (Offset)
305
 
                                offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
306
 
                                lineIdx += 1 # Incriment to the next line (Channels)
307
 
                                
308
 
                                # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
309
 
                                # newChannel references indecies to the motiondata,
310
 
                                # if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended 
311
 
                                # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
312
 
                                newChannel = [-1, -1, -1, -1, -1, -1] 
313
 
                                for channel in lines[lineIdx][2:]:
314
 
                                        channelIndex += 1 # So the index points to the right channel
315
 
                                        if channel == 'Xposition':
316
 
                                                newChannel[0] = channelIndex
317
 
                                        elif channel == 'Yposition':
318
 
                                                newChannel[1] = channelIndex
319
 
                                        elif channel == 'Zposition':
320
 
                                                newChannel[2] = channelIndex
321
 
                                        elif channel == 'Xrotation':
322
 
                                                newChannel[3] = channelIndex
323
 
                                        elif channel == 'Yrotation':
324
 
                                                newChannel[4] = channelIndex
325
 
                                        elif channel == 'Zrotation':
326
 
                                                newChannel[5] = channelIndex
327
 
                                
328
 
                                channelList.append(newChannel)
329
 
                                
330
 
                                channels = lines[lineIdx][2:]
331
 
                                
332
 
                                # Call funtion that uses the gatrhered data to make an empty.
333
 
                                makeJoint(name, parent, offset, channels)
334
 
                                
335
 
                                # If we have another child then we can call ourselves a parent, else 
336
 
                                parent.append(name)
337
 
        
338
 
                        # Account for an end node
339
 
                        if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name after 'End Site' but we will ignore it.
340
 
                                lineIdx += 2 # Incriment to the next line (Offset)
341
 
                                offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
342
 
                                makeEnd(parent, offset)
343
 
                                
344
 
                                # Just so we can remove the Parents in a uniform way- End end never has kids
345
 
                                # so this is a placeholder
346
 
                                parent.append(None)
347
 
                        
348
 
                        if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == '}': # == ['}']
349
 
                                parent.pop() # Remove the last item
350
 
                        
351
 
                        #=============================================#
352
 
                        # BVH Structure loaded, Now import motion     #
353
 
                        #=============================================#         
354
 
                        if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == 'MOTION':
355
 
                                print '\nImporting motion data'
356
 
                                lineIdx += 3 # Set the cursor to the first frame
357
 
                                
358
 
                                #=============================================#
359
 
                                # Add a ZERO keyframe, this keeps the rig     #
360
 
                                # so when we export we know where all the     #
361
 
                                # joints start from                           #
362
 
                                #=============================================#
363
 
                                
364
 
                                for obIdx, ob in enumerate(objectList):
365
 
                                        obname = ob.name
366
 
                                        if channelList[obIdx][0] != -1:
367
 
                                                objectCurveMapping[obname, 'LocX'].addBezier((currentFrame,0))
368
 
                                                objectMotiondataMapping[obname, 'LocX'] = []
369
 
                                        if channelList[obIdx][1] != -1:
370
 
                                                objectCurveMapping[obname, 'LocY'].addBezier((currentFrame,0))
371
 
                                                objectMotiondataMapping[obname, 'LocY'] = []
372
 
                                        if channelList[obIdx][2] != -1:
373
 
                                                objectCurveMapping[obname, 'LocZ'].addBezier((currentFrame,0))
374
 
                                                objectMotiondataMapping[obname, 'LocZ'] = []
375
 
                                        if\
376
 
                                        channelList[obIdx][3] != -1 or\
377
 
                                        channelList[obIdx][4] != -1 or\
378
 
                                        channelList[obIdx][5] != -1:
379
 
                                                objectMotiondataMapping[obname, 'RotX'] = []
380
 
                                                objectMotiondataMapping[obname, 'RotY'] = []
381
 
                                                objectMotiondataMapping[obname, 'RotZ'] = []
382
 
                                
383
 
                                #=============================================#
384
 
                                # Loop through frames, each line a frame      #
385
 
                                #=============================================#                 
386
 
                                MOTION_DATA_LINE_LEN = len(lines[lineIdx])
387
 
                                while lineIdx < len(lines):
388
 
                                        line = lines[lineIdx]
389
 
                                        if MOTION_DATA_LINE_LEN != len(line):
390
 
                                                print 'ERROR: Incomplete motion data on line %i, finishing import.' % lineIdx
391
 
                                                break
392
 
                                                
393
 
                                        # Exit loop if we are past the motiondata.
394
 
                                        # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS'
395
 
                                        # I dont know what they do and I dont care, they'll be ignored here.
396
 
                                        if len(line) < len(objectList):
397
 
                                                print '...ending on unknown tags'
398
 
                                                break
399
 
                                        
400
 
                                        
401
 
                                        currentFrame += 1 # Incriment to next frame
402
 
                                                                        
403
 
                                        #=============================================#
404
 
                                        # Import motion data and assign it to an IPO    #
405
 
                                        #=============================================#
406
 
                                        line.append(0.0) # Use this as a dummy var for objects that dont have a loc/rotate channel.
407
 
                                        
408
 
                                        if debug: Blender.Redraw() 
409
 
                                        for obIdx, ob in enumerate(objectList):
410
 
                                                obname = ob.name
411
 
                                                obChannel = channelList[obIdx] 
412
 
                                                if channelList[obIdx][0] != -1:
413
 
                                                        objectMotiondataMapping[obname, 'LocX'].append((currentFrame, scale * float(  line[obChannel[0]]  )))
414
 
                                                        
415
 
                                                if channelList[obIdx][1] != -1:
416
 
                                                        objectMotiondataMapping[obname, 'LocY'].append((currentFrame, scale * float(  line[obChannel[1]]         )))
417
 
 
418
 
                                                if channelList[obIdx][2] != -1:
419
 
                                                        objectMotiondataMapping[obname, 'LocZ'].append((currentFrame, scale * float(  line[obChannel[2]]  )))
420
 
                                                
421
 
                                                if obChannel[3] != -1 or obChannel[4] != -1 or obChannel[5] != -1:                                              
422
 
                                                        x, y, z = eulerRotate(float( line[obChannel[3]] ), float( line[obChannel[4]] ), float( line[obChannel[5]] ))
423
 
                                                        x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
424
 
                                                        motionMappingRotX = objectMotiondataMapping[obname, 'RotX']
425
 
                                                        motionMappingRotY = objectMotiondataMapping[obname, 'RotY']
426
 
                                                        motionMappingRotZ = objectMotiondataMapping[obname, 'RotZ']
427
 
                                                        
428
 
                                                        # Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
429
 
                                                        # Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
430
 
                                                        if len(motionMappingRotX) > 1:
431
 
                                                                while (motionMappingRotX[-1][1] - x) > 18: x+=36
432
 
                                                                while (motionMappingRotX[-1][1] - x) < -18: x-=36
433
 
                                                                
434
 
                                                                while (motionMappingRotY[-1][1] - y) > 18: y+=36
435
 
                                                                while (motionMappingRotY[-1][1] - y) < -18: y-=36
436
 
                                                                
437
 
                                                                while (motionMappingRotZ[-1][1] - z) > 18: z+=36
438
 
                                                                while (motionMappingRotZ[-1][1] - z) < -18: z-=36
439
 
                                                        
440
 
                                                        motionMappingRotX.append((currentFrame, x))
441
 
                                                        motionMappingRotY.append((currentFrame, y))
442
 
                                                        motionMappingRotZ.append((currentFrame, z))
443
 
                                                # Done importing motion data #
444
 
                                        
445
 
                                        lineIdx += 1
446
 
                                
447
 
                                #=======================================#
448
 
                                # Now Write the motion to the IPO's     #
449
 
                                #=======================================#
450
 
                                for key, motion_data in objectMotiondataMapping.iteritems():
451
 
                                        
452
 
                                        # Strip the motion data where all the points have the same falue.
453
 
                                        i = len(motion_data) -2
454
 
                                        while i > 0 and len(motion_data) > 2:
455
 
                                                if motion_data[i][1] == motion_data[i-1][1] == motion_data[i+1][1]:
456
 
                                                        motion_data.pop(i)
457
 
                                                i-=1
458
 
                                        # Done stripping.                                               
459
 
                                        
460
 
                                        obname, tx_type = key
461
 
                                        curve = objectCurveMapping[obname, tx_type]
462
 
                                        for point_data in motion_data:
463
 
                                                curve.addBezier( point_data )
464
 
                                # Imported motion to an IPO
465
 
                                
466
 
                                # No point in looking further, when this loop is done
467
 
                                # There is nothine else left to do                      
468
 
                                break
469
 
                                
470
 
                        # Main file loop
471
 
                        lineIdx += 1
472
 
                        
473
 
                print 'bvh import time for %i frames: %.6f' % (currentFrame, Blender.sys.time() - time1)
474
 
                Window.RedrawAll()
475
 
                Window.WaitCursor(0)
476
 
        
477
 
        Blender.Window.FileSelector(loadBVH, "Import BVH")
478
 
        
479
 
        #=============#
480
 
        # TESTING     #
481
 
        #=============#
482
 
        '''
483
 
        #loadBVH('/metavr/mocap/bvh/boxer.bvh')
484
 
        #loadBVH('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
485
 
        #loadBVH('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
486
 
        #loadBVH('/metavr/mocap/bvh/walk4.bvh') # 0 channels
487
 
        scale  = 0.01
488
 
        import os
489
 
        DIR = '/metavr/mocap/bvh/'
490
 
        for f in os.listdir(DIR):
491
 
                if f.endswith('.bvh'):
492
 
                        s = Scene.New(f)
493
 
                        s.makeCurrent()
494
 
                        loadBVH(DIR + f)
495
 
        '''
496
 
if __name__ == '__main__':
497
 
        main()
 
 
b'\\ No newline at end of file'