forked from JonnylikesJazz/Wadblender-Anim-Tool
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanimations.py
More file actions
146 lines (117 loc) · 4.94 KB
/
animations.py
File metadata and controls
146 lines (117 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import json
from typing import List, Tuple, Dict
from collections import defaultdict
import bpy
from mathutils import Euler
def create_animations(item_idx, rig, bonenames, animations, options):
if rig.animation_data is None:
rig.animation_data_create()
for idx, animation in enumerate(animations):
if item_idx in options.anim_names and str(idx) in options.anim_names[item_idx]:
name = ' - '.join((rig.name, str(idx).zfill(3), options.anim_names[item_idx][str(idx)]))
else:
name = ' - '.join((rig.name, str(idx).zfill(3)))
action = bpy.data.actions.new(name)
offsets = [keyframe.offset for keyframe in animation.keyFrames]
rotations = defaultdict(list)
for keyframe in animation.keyFrames:
for bonename, rot in zip(bonenames, keyframe.rotations):
angle = Euler(rot, 'ZXY')
angle = angle.to_quaternion()
rotations[bonename].append(angle)
for axis in [0, 1, 2]:
fc = action.fcurves.new(
data_path='pose.bones["{}"].location'.format(bonenames[0]), index=axis)
keyframe_points = fc.keyframe_points
keyframe_points.add(len(offsets))
for j, val in enumerate(offsets):
k = 0
v = val[axis]
keyframe_points[j].co = (j, v / options.scale)
for bonename in bonenames:
for axis in [0, 1, 2, 3]:
data_path = 'pose.bones["{}"].rotation_quaternion'.format(
bonename)
fc = action.fcurves.new(data_path=data_path, index=axis)
keyframe_points = fc.keyframe_points
keyframe_points.add(len(rotations[bonename]))
for j, rot in enumerate(rotations[bonename]):
keyframe_points[j].co = (j, rot[axis])
action.use_fake_user = True
track = rig.animation_data.nla_tracks.new()
name = action.name
action = bpy.data.actions[name]
track.name = name
track.strips.new(action.name, start=0, action=action)
if options.export_fbx:
bpy.ops.object.select_all(action='DESELECT')
rig.select_set(True)
bpy.context.view_layer.objects.active = rig
filepath = options.path + '\\{}.fbx'.format(rig.name)
bpy.ops.export_scene.fbx(
filepath=filepath, axis_forward='Z', use_selection=True,
add_leaf_bones=False, bake_anim_use_all_actions=False,
bake_anim_use_nla_strips=True
)
def save_animations_data(item_idx, animations, filename, options):
path = options.path
states = set()
for idx, a in enumerate(animations):
states.add(a.stateID)
class AnimationData:
idx: str
name: str
bboxes: List[Tuple]
stateChanges: Dict[str, List[Tuple]]
commands: List[Tuple[int]]
frameDuration: int
speed: int
acceleration: int
frameStart: int
frameEnd: int
frameIn: int
nextAnimation: str
saves = {}
animations_names = options.anim_names
states_names = options.state_names
for state in states:
animations_state = []
for idx, a in enumerate(animations):
if a.stateID != state:
continue
data = AnimationData()
data.idx = str(idx).zfill(3)
str_idx = str(idx)
if item_idx in animations_names and str_idx in animations_names[item_idx]:
data.name = animations_names[item_idx][str_idx]
else:
data.name = data.idx
data.frameDuration = a.frameDuration
data.speed = a.speed
data.acceleration = a.acceleration
data.frameStart = a.frameStart
data.frameEnd = a.frameEnd
data.frameIN = a.frameIn
data.nextAnimation = str(a.nextAnimation).zfill(3)
bboxes = []
for keyframe in a.keyFrames:
x0, y0, z0 = keyframe.bb1
x1, y1, z1 = keyframe.bb2
bboxes.append((x0, y0, z0, x1, y1, z1))
data.bboxes = bboxes
data.commands = a.commands
data.stateChanges = {}
for sc, dispatches in a.stateChanges.items():
d = []
for dispatch in dispatches:
nextAnim = str(dispatch[2]).zfill(3)
d.append([dispatch[0], dispatch[1], nextAnim, dispatch[3]])
data.stateChanges[str(sc).zfill(3)] = d
animations_state.append(data.__dict__)
s = str(state).zfill(3)
if item_idx in states_names and str(state) in states_names[item_idx]:
saves[s] = states_names[item_idx][str(state)], animations_state
else:
saves[s] = 'UNKNOWN_STATE', animations_state
with open(path + '\\' + filename + '.json', 'w') as f:
json.dump(saves, f, indent=4)