123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #!/usr/bin/env python
- __author__ = 'Andrew Dunai <[email protected]>'
- import sys
- import json
- import argparse
- import re
- from collections import namedtuple
- try:
- from PyQt4 import QtGui
- import argparseui
- except ImportError:
- CAN_GUI = False
- else:
- CAN_GUI = True
- range_regexp = re.compile(r'^([\w\d]+)\=([\d]+)\.\.([\d]+)$')
- Range = namedtuple('Range', ('name', 'start', 'end'))
- def parse_range(value):
- match = range_regexp.match(value)
- if not match:
- raise argparse.ArgumentTypeError('Ranges should be in form "name=frame..frame"')
- return Range(match.group(1), int(match.group(2)) - 1, int(match.group(3)) - 1)
- epilog = 'example:\n %(prog)s -i model.js -o model.new.js idle=1..10 walk=11..20'
- if not CAN_GUI:
- epilog += '\npro tip:\n Install PyQt4 and argparseui packages to use GUI ("-u" option).'
- epilog += '\nCreated by {}'.format(__author__)
- parser = argparse.ArgumentParser(
- description='Split THREE.js model animation into seperate parts.',
- epilog=epilog,
- formatter_class=argparse.RawDescriptionHelpFormatter
- )
- CAN_GUI and parser.add_argument('-u', '--gui', help='run in GUI', dest='gui', action='store_true')
- parser.add_argument('-i', metavar='FILE', help='input file name', required=True, dest='source', type=argparse.FileType('r'))
- parser.add_argument('-o', metavar='FILE', help='output file name', required=True, dest='destination', type=argparse.FileType('w'))
- parser.add_argument('range', nargs='+', help='range in format "name=frame..frame"', type=parse_range)
- def process(parser):
- args = parser.parse_args()
- data = json.loads(args.source.read())
- animation = data.get('animation')
- fps = float(animation.get('fps'))
- length = float(animation.get('length'))
- frame_count = int(length * fps)
- frame_duration = 1.0 / fps
- all_hierarchy = animation.get('hierarchy')
- animations = {}
- for r in args.range:
- # Create animation & hierarchy
- hierarchy = []
- animation = {
- 'name': r.name,
- 'fps': fps,
- 'length': (r.end - r.start) * frame_duration,
- 'hierarchy': hierarchy
- }
- # Go through each bone animation
- for bone in all_hierarchy:
- keys = [key for key in bone['keys'] if (key['time'] >= r.start * frame_duration) and (key['time'] <= r.end * frame_duration)]
- # Patch time
- time = 0.0
- for key in keys:
- key['time'] = round(time, 3)
- time += frame_duration
- new_bone = {
- 'parent': bone['parent'],
- 'keys': keys
- }
- hierarchy.append(new_bone)
- animations[r.name] = animation
- del data['animation']
- data['animations'] = animations
- args.destination.write(json.dumps(data))
- if '-u' in sys.argv and CAN_GUI:
- app = QtGui.QApplication(sys.argv)
- a = argparseui.ArgparseUi(parser)
- a.show()
- app.exec_()
-
- if a.result() == 1:
- process(a)
- else:
- process(parser)
|