Files
AIGame/Tools/generate_enemy_motions.py
T

46 lines
2.1 KiB
Python

"""Generate missing enemy actions sequentially on the recipe's SAME rig."""
import argparse
import hashlib
import json
from pathlib import Path
import subprocess
import sys
REPO=Path(__file__).resolve().parents[1]
def seal_generated_motion(folder):
"""Attach output hashes after the backend has completed its own manifest."""
receipt=folder/'motion_request.json'
record=json.loads(receipt.read_text(encoding='utf-8-sig'))
result=json.loads((folder/'unimate_manifest.json').read_text(encoding='utf-8-sig'))
if result['prompt']!=record['prompt']:
raise ValueError('Generated output caption differs from request')
record.update(status='generated',remote_job=result['remote_job'],
source_fbx_sha256=hashlib.sha256((folder/'animated.fbx').read_bytes()).hexdigest())
temporary=receipt.with_suffix('.pending.json')
temporary.write_text(json.dumps(record,indent=2),encoding='utf-8')
temporary.replace(receipt)
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--recipe',type=Path,required=True)
parser.add_argument('--motions',nargs='+',choices=('Idle','Walk','Attack'),default=['Idle','Walk','Attack'])
parser.add_argument('--device',choices=('cuda','cpu'),default='cuda')
args=parser.parse_args()
recipe=json.loads(args.recipe.read_text(encoding='utf-8-sig'))
for motion in recipe['motions']:
if motion['name'] not in args.motions:
continue
command=[sys.executable,str(REPO/'Tools/generate_animal_walk.py'),
'--rig',str(REPO/recipe['rigSource']),'--out',str(REPO/motion['sourceDir']),
'--motion',motion['name'],'--duration',str(motion['duration']),
'--device',args.device,
'--face-right',recipe['faceRight'],'--face-left',recipe['faceLeft'],
'--prompt',motion['prompt']]
print('GENERATE',recipe['id'],motion['name'],flush=True)
subprocess.run(command,cwd=REPO,check=True)
seal_generated_motion(REPO/motion['sourceDir'])
if __name__=='__main__':
main()