File size: 3,526 Bytes
da855ff |
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 |
import numpy as np
from scipy import interpolate
from anim import bvh, quat
def change_bvh(filename, savename, order=None, fps=None, pace=1.0, center=False):
anim_data = bvh.load(filename)
output = anim_data.copy()
if order is not None:
output["order"] = order
rotations = quat.unroll(quat.from_euler(np.radians(anim_data['rotations']), order=anim_data['order']))
output["rotations"] = np.degrees(quat.to_euler(rotations, order=output["order"]))
if pace is not None or fps is not None:
if fps is None:
fps = 1.0 / anim_data["frametime"]
positions = anim_data['positions']
rotations = quat.unroll(quat.from_euler(np.radians(anim_data['rotations']), order=anim_data['order']))
nframes = positions.shape[0]
nbones = positions.shape[1]
original_times = np.linspace(0, nframes - 1, nframes)
sample_times = np.linspace(
0, nframes - 1, int(pace * (nframes * (fps * anim_data["frametime"]) - 1))
)
output["positions"] = interpolate.griddata(original_times, output["positions"].reshape([nframes, -1]),
sample_times, method='cubic').reshape([len(sample_times), nbones, 3])
rotations = interpolate.griddata(original_times, rotations.reshape([nframes, -1]),
sample_times, method='cubic').reshape([len(sample_times), nbones, 4])
rotations = quat.normalize(rotations)
output["rotations"] = np.degrees(quat.to_euler(rotations, order=output["order"]))
output["frametime"] = 1.0 / fps
if center:
lrot = quat.from_euler(np.radians(output["rotations"]), output["order"])
offset_pos = output["positions"][0:1, 0:1].copy() * np.array([1, 0, 1])
offset_rot = lrot[0:1, 0:1].copy() * np.array([1, 0, 1, 0])
root_pos = quat.mul_vec(quat.inv(offset_rot), output["positions"][:, 0:1] - offset_pos)
output["positions"][:, 0:1] = quat.mul_vec(quat.inv(offset_rot),
output["positions"][:, 0:1] - offset_pos)
output["rotations"][:, 0:1] = np.degrees(
quat.to_euler(quat.mul(quat.inv(offset_rot), lrot[:, 0:1]), order=output["order"]))
bvh.save(savename, output)
def write_bvh(
filename,
V_root_pos,
V_root_rot,
V_lpos,
V_lrot,
parents,
names,
order,
dt,
start_position=None,
start_rotation=None,
):
if start_position is not None and start_rotation is not None:
offset_pos = V_root_pos[0:1].copy()
offset_rot = V_root_rot[0:1].copy()
V_root_pos = quat.mul_vec(quat.inv(offset_rot), V_root_pos - offset_pos)
V_root_rot = quat.mul(quat.inv(offset_rot), V_root_rot)
V_root_pos = (
quat.mul_vec(start_rotation[np.newaxis], V_root_pos) + start_position[np.newaxis]
)
V_root_rot = quat.mul(start_rotation[np.newaxis], V_root_rot)
V_lpos = V_lpos.copy()
V_lrot = V_lrot.copy()
V_lpos[:, 0] = quat.mul_vec(V_root_rot, V_lpos[:, 0]) + V_root_pos
V_lrot[:, 0] = quat.mul(V_root_rot, V_lrot[:, 0])
bvh.save(
filename,
dict(
order=order,
offsets=V_lpos[0],
names=names,
frametime=dt,
parents=parents,
positions=V_lpos,
rotations=np.degrees(quat.to_euler(V_lrot, order=order)),
),
)
|