Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-05-14 20:22:21 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-05-14 20:22:21 +0400
commit8c5adbcd98b20e61f77263a2fb9095d331785a10 (patch)
tree2e9c40049cc3a9002a8e805c63db6f277f00eb89 /io_anim_bvh
parent1ef45bae5521b834dd89d8f85a64926e120c8341 (diff)
support to export different rotation orders as well as pose bone native order.
Diffstat (limited to 'io_anim_bvh')
-rw-r--r--io_anim_bvh/__init__.py16
-rw-r--r--io_anim_bvh/export_bvh.py41
-rw-r--r--io_anim_bvh/import_bvh.py2
3 files changed, 51 insertions, 8 deletions
diff --git a/io_anim_bvh/__init__.py b/io_anim_bvh/__init__.py
index e8b51a77..5cdc79f2 100644
--- a/io_anim_bvh/__init__.py
+++ b/io_anim_bvh/__init__.py
@@ -37,7 +37,8 @@ if "bpy" in locals():
import imp
if "import_bvh" in locals():
imp.reload(import_bvh)
-
+ if "export_bvh" in locals():
+ imp.reload(export_bvh)
import bpy
from bpy.props import StringProperty, FloatProperty, IntProperty, BoolProperty, EnumProperty
@@ -95,6 +96,19 @@ class ExportBVH(bpy.types.Operator, ExportHelper):
frame_start = IntProperty(name="Start Frame", description="Starting frame to export", default=0)
frame_end = IntProperty(name="End Frame", description="End frame to export", default=0)
+ rotate_mode = EnumProperty(items=(
+ ('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
+ ('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
+ ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
+ ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
+ ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
+ ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
+ ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
+ ),
+ name="Rotation",
+ description="Rotation conversion.",
+ default='NATIVE')
+
@classmethod
def poll(cls, context):
obj = context.object
diff --git a/io_anim_bvh/export_bvh.py b/io_anim_bvh/export_bvh.py
index 2a49f083..6d36e587 100644
--- a/io_anim_bvh/export_bvh.py
+++ b/io_anim_bvh/export_bvh.py
@@ -23,8 +23,12 @@
import bpy
+def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0, rotate_mode="NATIVE"):
-def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0):
+ def ensure_rot_order(rot_order_str):
+ if set(rot_order_str) != {'X', 'Y', 'Z'}:
+ rot_order_str = "XYZ"
+ return rot_order_str
from mathutils import Matrix, Vector, Euler
from math import degrees
@@ -62,9 +66,15 @@ def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0):
indent_str = "\t" * indent
bone = arm.bones[bone_name]
+ pose_bone = obj.pose.bones[bone_name]
loc = bone.head_local
node_locations[bone_name] = loc
+ if rotate_mode == "NATIVE":
+ rot_order_str = ensure_rot_order(pose_bone.rotation_mode)
+ else:
+ rot_order_str = rotate_mode
+
# make relative if we can
if bone.parent:
loc = loc - node_locations[bone.parent.name]
@@ -77,9 +87,9 @@ def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0):
file.write("%s{\n" % indent_str)
file.write("%s\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * global_scale, loc.y * global_scale, loc.z * global_scale))
if bone.use_connect and bone.parent:
- file.write("%s\tCHANNELS 3 Xrotation Yrotation Zrotation\n" % indent_str)
+ file.write("%s\tCHANNELS 3 %srotation %srotation %srotation\n" % (indent_str, rot_order_str[0], rot_order_str[1], rot_order_str[2]))
else:
- file.write("%s\tCHANNELS 6 Xposition Yposition Zposition Xrotation Yrotation Zrotation\n" % indent_str)
+ file.write("%s\tCHANNELS 6 Xposition Yposition Zposition %srotation %srotation %srotation\n" % (indent_str, rot_order_str[0], rot_order_str[1], rot_order_str[2]))
if my_children:
# store the location for the children
@@ -137,13 +147,30 @@ def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0):
"rest_local_imat", # rest_local_mat inverted
"prev_euler", # last used euler to preserve euler compability in between keyframes
"connected", # is the bone connected to the parent bone?
+ "rot_order",
+ "rot_order_str",
)
+ _eul_order_lookup = {
+ 'XYZ': (0, 1, 2),
+ 'XZY': (0, 2, 1),
+ 'YXZ': (1, 0, 2),
+ 'YZX': (1, 2, 0),
+ 'ZXY': (2, 0, 1),
+ 'ZYX': (2, 1, 0)}
+
def __init__(self, bone_name):
self.name = bone_name
self.rest_bone = arm.bones[bone_name]
self.pose_bone = obj.pose.bones[bone_name]
+ if rotate_mode == "NATIVE":
+ self.rot_order_str = ensure_rot_order(self.pose_bone.rotation_mode)
+ else:
+ self.rot_order_str = rotate_mode
+
+ self.rot_order = __class__._eul_order_lookup[self.rot_order_str]
+
self.pose_mat = self.pose_bone.matrix
mat = self.rest_bone.matrix
@@ -156,7 +183,7 @@ def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0):
self.rest_local_imat = self.rest_local_mat.inverted()
self.parent = None
- self.prev_euler = Euler((0.0, 0.0, 0.0))
+ self.prev_euler = Euler((0.0, 0.0, 0.0), self.rot_order_str)
self.connected = (self.rest_bone.use_connect and self.rest_bone.parent)
def update_posedata(self):
@@ -209,12 +236,12 @@ def write_armature(context, filepath, frame_start, frame_end, global_scale=1.0):
loc = mat_final.to_translation() + dbone.rest_bone.head
# keep eulers compatible, no jumping on interpolation.
- rot = mat_final.to_3x3().inverted().to_euler('XYZ', dbone.prev_euler)
+ rot = mat_final.to_3x3().inverted().to_euler(dbone.rot_order_str, dbone.prev_euler)
if not dbone.connected:
file.write("%.6f %.6f %.6f " % (loc * global_scale)[:])
- file.write("%.6f %.6f %.6f " % (-degrees(rot[0]), -degrees(rot[1]), -degrees(rot[2])))
+ file.write("%.6f %.6f %.6f " % (-degrees(rot[dbone.rot_order[0]]), -degrees(rot[dbone.rot_order[1]]), -degrees(rot[dbone.rot_order[2]])))
dbone.prev_euler = rot
@@ -229,12 +256,14 @@ def save(operator, context, filepath="",
frame_start=-1,
frame_end=-1,
global_scale=1.0,
+ rotate_mode="NATIVE",
):
write_armature(context, filepath,
frame_start=frame_start,
frame_end=frame_end,
global_scale=global_scale,
+ rotate_mode=rotate_mode,
)
return {'FINISHED'}
diff --git a/io_anim_bvh/import_bvh.py b/io_anim_bvh/import_bvh.py
index d0f3fde8..c4d358d1 100644
--- a/io_anim_bvh/import_bvh.py
+++ b/io_anim_bvh/import_bvh.py
@@ -45,7 +45,7 @@ class bvh_node_class(object):
'has_rot', # Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1)
'temp') # use this for whatever you want
- _eul_order_lookup = {\
+ _eul_order_lookup = {
(0, 1, 2): 'XYZ',
(0, 2, 1): 'XZY',
(1, 0, 2): 'YXZ',